積累的VC編程小技巧之圖標、光標及位圖
1.圖標透明
(1).Windows中的圖標其實是有兩個圖像組成的,其中一個用于與它要顯示的位置的圖像做“AND”操作,另一個作“XOR”操作。
透明:用“白色”AND,用“黑色”XOR
反色:用“白色”AND,用“白色”XOR
正常色:用“黑色”AND,用正常顏色XOR.
(2). WIN9X中好像是對像素的操作實現透明的
WIN2K中就有API直接實現透明了!
WIN2K中
GetWindowLong
SetWindowLong
SetLayeredWindowAttributes
三個API就可以實現透明了!
(3)
::DrawIconEx(pDC->GetSafeHdc(),point.x,point.y,icon,icosize,icosize,0,NULL,DI_NORMAL);
2.如何獲得其他程序的圖標,并顯示在View中
[問題提出]
有的時候,如:類資源管理器會遇到獲得程序圖標并顯示的操作,如何實現呢?
[解決方法]
SDK函數SHGetFileInfo來獲得有關文件的很多信息:如大小圖標,屬性,類型等.
[程序實現]
建立名為My的SDI工程.在OnPaint()函數中加入:
void CMyView::OnPaint()
{
CPaintDC dc(this); // device context for painting
HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0);
if (hIcon && hIcon!=(HICON)-1)
dc.DrawIcon(10,10,hIcon);
// TODO: Add your message handler code here
// Do not call CView::OnPaint() for painting messages
}
說明:_T("NotePad.exe")指的是要獲得什么程序的圖標.
或者在OnDraw()中(此時必須保證沒有OnPaint()函數,想想為何?)
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0);
if (hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon);
}
3.如何改變默認的光標形狀
在對話框/窗口/你需要的地方加上對WM_SETCURSOR消息的處理.
BOOL MyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TOD Add your message handler code here and/or call default
::SetCursor(AfxGetApp()->LoadCursor(IDC_MYCURSOR));
return TRUE;
//return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
窗口類光標風格不能為NULL.
4.改變應用程序的圖標靜態更改
修改圖標資源IDR_MAINFRAME。它有兩個圖標,一個是16*16的,另一個是32*32的,注意要一起修改。
動態更改: 向主窗口發送WM_SETICON消息.代碼如下:
HICON hIcon=AfxGetApp()->LoadIcon(IDI_ICON);
ASSERT(hIcon);
AfxGetMainWnd()->SendMessage(WM_SETICON,TRUE,(LPARAM)hIcon);
5.更改窗口圖標并將其顯示在任務欄
以下兩個函數可以為應用程序中的各子窗口顯示一個任務條到任務欄并更改它們的圖標。對那些象QQ一樣隱藏主窗口的應用程序特別有用。
//函數用途:更改一個窗口的圖標并將其顯示在任務欄、任務切換條、任務管理器里
//參數說明:
//hWnd 要改變圖標的窗口句柄
//hLargeIcon 顯示到任務切換條上的圖標 32*32
//hSmallIcon 顯示到除任務切換條之外的圖標 16*16
//hIcon 顯示的圖標,32*32,在顯示到任務切換條之外的其余地方時會被自動壓縮成16*16的。
//注釋:
//此函數對于模式對話框無能為力。
//如果HICON 為NULL,函數不改變窗口圖標,但是將原有圖標顯示到任務欄、
// 任務切換條、任務管理器里。
//此函數是通過將窗口的父窗口指針置空來實現將圖標顯示到任務欄、任務切換條、
// 任務管理器里的,所以調用完成后,其父窗口指針不再可用。
BOOL SendWndIconToTaskbar(HWND hWnd,HICON hLargeIcon,HICON hSmallIcon);
BOOL SendWndIconToTaskbar(HWND hWnd,HICON hIcon);
BOOL CUIApp::SendWndIconToTaskbar(HWND hWnd,HICON hLargeIcon,HICON hSmallIcon)
{
BOOL ret = TRUE;
ASSERT(hWnd);
if(!::IsWindow(hWnd))
return FALSE;
//獲取窗口指針
CWnd* pWnd;
pWnd = pWnd->FromHandle(hWnd);
ASSERT(pWnd);
if(!pWnd)
return FALSE;
//將父窗口設為NULL
if(pWnd->GetParent())
if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0)
return FALSE;
if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW)))
ret = FALSE;
//設置窗口圖標
if(hLargeIcon && hSmallIcon)
{
pWnd->SetIcon(hSmallIcon,FALSE);
pWnd->SetIcon(hLargeIcon,TRUE);
}
return ret;
}
BOOL CUIApp::SendWndIconToTaskbar(HWND hWnd,HICON hIcon)
{
BOOL ret = TRUE;
ASSERT(hWnd);
if(!::IsWindow(hWnd))
return FALSE;
//獲取窗口指針
CWnd* pWnd;
pWnd = pWnd->FromHandle(hWnd);
ASSERT(pWnd);
if(!pWnd)
return FALSE;
//將父窗口設為NULL
if(pWnd->GetParent())
if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0)
return FALSE;
if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW)))
ret = FALSE;
//設置窗口圖標
pWnd->SetIcon(hIcon,TRUE);
pWnd->SetIcon(hIcon,FALSE);
return ret;
}
6.如何將位圖縮放顯示在Static控件中
//在Staic控件內顯示位圖
void CShowBmpInDlgDlg::ShowBmpInStaic()
{
CBitmap hbmp;
HBITMAP hbitmap;
//將pStatic指向要顯示的地方
CStatic *pStaic;
pStaic=(CStatic*)GetDlgItem(IDC_IMAGE);
//裝載資源 MM.bmp是我的一個文件名,用你的替換
hbitmap=(HBITMAP)::LoadImage (::AfxGetInstanceHandle(),"MM.bmp",
IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
hbmp.Attach(hbitmap);
//獲取圖片格式
BITMAP bm;
hbmp.GetBitmap(&bm);
CDC dcMem;
dcMem.CreateCompatibleDC(GetDC());
CBitmap *poldBitmap=(CBitmap*)dcMem.SelectObject(hbmp);
CRect lRect;
pStaic->GetClientRect(&lRect);
//顯示位圖
pStaic->GetDC()->StretchBlt(lRect.left ,lRect.top ,lRect.Width(),lRect.Height(),
&dcMem,0 ,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
dcMem.SelectObject(&poldBitmap);
}