Sleeping

Note Book

DialogBox的若干问题

今天继续折腾那个List Box控件,发现一个问题,当对话框出来之后,被主窗体给刷屏了,不能得到子窗体的句柄。后经仔细调试,发现一些端倪。首先在调用 DialogBox函数时 ,所生成的Dialog(我这里的Dialog面板里有一个Edit控件 两个按钮控件 和一个List Box控件)依次产生的消息队列如下所示:
WM_SETFONT    0x0030                 设置字体
WM_INITDIALOG 0x0110                 初始化Dialog
WM_WINDOWPOSCHANGING            0x0046                窗体大小 位置等转变的消息
WM_NCACTIVATE   0x0086          改变一个非工作区域 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) 一直循环以下的两个消息
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)函数更改想要返回的值.切记一定要马上调用该函数在返回TRUE之前,尽可能早地通过DWL_MSGRESULT去改写真正的Result,by a nested dialog box message.  他妈的这句怎么翻译?


现在都开始怀疑弄这些消息有什么用,用MFC肯定是一个更好的选择。在List Box里增加和删除内容都是太烦了,都是通过SendMessage来完成的。不知道能坚持学到什么时候。

posted on 2008-10-07 21:42 祥子_随波逐流 阅读(2042) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理