今天繼續(xù)折騰那個List Box控件,發(fā)現(xiàn)一個問題,當對話框出來之后,被主窗體給刷屏了,不能得到子窗體的句柄。后經(jīng)仔細調試,發(fā)現(xiàn)一些端倪。首先在調用 DialogBox函數(shù)時 ,所生成的Dialog(我這里的Dialog面板里有一個Edit控件 兩個按鈕控件 和一個List Box控件)依次產(chǎn)生的消息隊列如下所示: WM_SETFONT 0x0030 設置字體 WM_INITDIALOG 0x0110 初始化Dialog WM_WINDOWPOSCHANGING 0x0046 窗體大小 位置等轉變的消息 WM_NCACTIVATE 0x0086 改變一個非工作區(qū)域 sent to a window when its nonclient area needs to be changed to indicate an active or inactive state. WM_ACTIVATE 0x0006 讓你窗體無效 并激活子窗體 WM_COMMAND 0x0111 (HIWORD(WPARAM))->LBN_SETFOCUS(4) ->LBN_KILLFOCUS(5) 消息命令 ListBox WM_USER 0x0400 用戶自定義消息 WM_NCACTIVATE 0x0086 WM_SHOWWINDOW 0x0018 顯示窗體 WM_WINDOWPOSCHANGING 0x0046 WM_NCPAINT 0x0085 The WM_NCPAINT message is sent to a window when its frame must be painted. WM_ERASEBKGND 0x0014 清楚窗口背景 WM_WINDOWPOSCHANGED 0x0047 WM_GETICON 0x007F 3次 The WM_GETICON message is sent to a window to retrieve a handle to the large or small icon associated with a window WM_NCCALCSIZE 0x0083 計算機窗體大小尺寸 WM_MOVE 0x0003 移動 WM_SIZE 0x0005 改變大小 WM_PAINT 0x000F 繪制窗體 WM_CTLCOLORBTN 0x0135 繪制按鈕的顏色 WM_CTLCOLORLISTBOX 0x0134 繪制Listbox的顏色 WM_CTLCOLOREDIT 0x0133 繪制Edit的顏色 WM_POWERBROADCAST 0x0218 broadcast to an application to notify it of power-management events while(1) 一直循環(huán)以下的兩個消息 WM_NCACTIVATE 0x0086 WM_WINDOWPOSCHANGING 0x0046
代碼如下:
BOOL CALLBACK ListBoxTest(HWND hWnd,UINT message , WPARAM wParam, LPARAM lParam)
  {
int wmId = LOWORD(wParam );
int wmEvent = HIWORD(wParam) ;
int i ;
HDC hDc ;
PAINTSTRUCT ps ;
HWND hListBox ;
switch(message)
  {
case WM_INITDIALOG:
hListBox = GetDlgItem(hWnd,IDC_LIST_TEST) ;
for(i = 0; MyData[i].Name[0] != 0 ; i++)
{
SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)MyData[i].Name) ;
SendMessage(hListBox,LB_SETITEMDATA, i ,(LPARAM)i) ;
}
SetFocus(hListBox);
return (TRUE) ;
case WM_PAINT:
hDc = BeginPaint(hWnd,&ps) ;
//MSGPRINT(_T("Print")) ;
EndPaint(hWnd,&ps);
break ;
case LB_ADDFILE:
break ;
case WM_COMMAND:
switch(wmId)
{
case IDC_LIST_TEST:
switch(wmEvent) {
case LBN_SELCHANGE:
//MSGPRINT(_T("LBN_SELCHANGE"));
break ;
case LBN_DBLCLK:
//MSGPRINT(_T("LBN_DBLCLK"));
break ;
case LBN_SETFOCUS:
//MSGPRINT(_T("LBN_SETFOCUS")) ;
break ;
case LBN_KILLFOCUS:
//MSGPRINT(_T("LBN_KILLFOCUS")) ;
break ;
}
return FALSE ;
break ;
case IDOK:
MSGPRINT(_T("IDOK"));
EndDialog(hWnd,0) ;
return TRUE;
break ;
case IDCANCEL:
MSGPRINT(_T("IDCANCEL"));
EndDialog(hWnd,0) ;
return TRUE ;
break ;
}
}
return FALSE;
}
如果最后返回TRUE那么窗體的著色會很有問題,Dialog的顏色和背景顏色完全一樣,導致不能看到一個窗體的存在,所以這里必須返回FALSE, MSDN作出的解釋如下:Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If the dialog box procedure returns FALSE, the dialog manager performs the default dialog operation in response to the message. 意即,如果這個窗體想處理哪個消息就返回TRUE,如果不想處理這個消息就返回FALSE,所以在最后應該返回False,即默認不處理那些消息而只算WM_INITDIALOG 和其它一些IDOK IDCANCEL的消息。 If the dialog box procedure processes a message that requires a specific return value, the dialog box procedure should set the desired return value by calling SetWindowLong(hwndDlg, DWL_MSGRESULT, lResult) immediately before returning TRUE. Note that you must call SetWindowLong immediately before returning TRUE; doing so earlier may result in the DWL_MSGRESULT value being overwritten by a nested dialog box message.
這個嘛 靠 英文 爛!勉勉強強 如果窗體在處理一個消息時需要顯示地返回一個值,那這個窗體應該在返回TRUE前調用SetWindoLong(hWndDlg,DWL_MSGRESULT,lpResult)函數(shù)更改想要返回的值.切記一定要馬上調用該函數(shù)在返回TRUE之前,盡可能早地通過DWL_MSGRESULT去改寫真正的Result,by a nested dialog box message. 他媽的這句怎么翻譯?
現(xiàn)在都開始懷疑弄這些消息有什么用,用MFC肯定是一個更好的選擇。在List Box里增加和刪除內容都是太煩了,都是通過SendMessage來完成的。不知道能堅持學到什么時候。
|