HWND GetDlgItem( 
  HWND hDlg, 
  int nIDDlgItem
); 
Parameters
hDlg 
[in] Handle to the dialog box that contains the control. 
nIDDlgItem 
[in] Specifies the identifier of the control to be retrieved. 
我现在在VS2005下的移动设备里用Win32编程,想试试看图片控件,来响应单击消息。但是无法活动该picture control的句柄。不知道怎么用,希望高手指点迷津:
// “About”框的消息处理程序。由主窗口程序点击“About”菜单响应的对话框的处理过程
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{ case WM_INITDIALOG:
{
// 创建一个“完成”按钮并调整其大小。
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
}
return (INT_PTR)TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
//自己添加的响应左键消息
case WM_LBUTTONDOWN:
RECT rect;
POINT point;
HWND hButton;
hButton = GetDlgItem(hDlg,IDC_Photo);//“IDC_Photo”是我在“IDD_ABOUTBOX”对话框上事先已经添加上去的一个PICTURE CONTROL控件的ID号
if(NULL == hButton)
{
MessageBox(NULL, _T("hButton = NULL"), _T("命令"), MB_OK);
LPVOID lpMsgBuf;   
FormatMessage(     
FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
FORMAT_MESSAGE_FROM_SYSTEM   |     
FORMAT_MESSAGE_IGNORE_INSERTS,   
NULL,   
GetLastError(),   
0,   //   Default   language   
(LPTSTR)&lpMsgBuf,   
0,   
NULL);    MessageBox(NULL, (LPCTSTR)lpMsgBuf, _T("命令"), MB_OK | MB_ICONINFORMATION);   
//   Free   the   buffer.   
LocalFree(lpMsgBuf);
}
if(FALSE == GetWindowRect(hButton,&rect))
{
MessageBox(NULL, _T("GetWindowRect(hButton,&rect)) = FALSE"), _T("命令"), MB_OK); 
}

GetCursorPos(&point); if(PtInRect(&rect,point))   
{   
MessageBox(NULL, _T("在本示范程序中,该命令的功能暂时缺省。"), _T("命令"), MB_OK); 
}
break; case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;#ifdef _DEVICE_RESOLUTION_AWARE
case WM_SIZE:
{
DRA::RelayoutDialog(
g_hInst, 
hDlg, 
DRA::GetDisplayMode() != DRA::Portrait ? MAKEINTRESOURCE(IDD_ABOUTBOX_WIDE) : MAKEINTRESOURCE(IDD_ABOUTBOX));
}
break;
#endif
}
return (INT_PTR)FALSE;
}
问题:为什么我在About对话框上随便的哪里单击都会弹出“hButton = NULL”呢?然后GetLastError()显示:此函数仅在Win32模式下有效。

解决方案 »

  1.   

    为什么不调用DefWindowProc?这是必须的。
      

  2.   

    在你的主对话类中LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc; switch (message)
    {
    case WM_COMMAND:
    wmId    = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    // 分析菜单选择:
    switch (wmId)
    {
    case IDM_ABOUT:
    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); //这里不要用DialogBox,换成CreateWindow和ShowWindow来显示About
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    // TODO: 在此添加任意绘图代码...
    EndPaint(hWnd, &ps);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }在About对话框的窗口类中,你模仿下主对话框的类,写return DefWindowProc(hWnd, message, wParam, lParam);
    按主对话框的类照猫画虎就行了
      

  3.   

    这是主对话框程序:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc; static SHACTIVATEINFO s_sai; switch (message) 
    {
    case WM_COMMAND:
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // 分析菜单选择:
    switch (wmId)
    {
    case IDM_HELP_ABOUT:
    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
    break;
    case IDM_OK:
    SendMessage (hWnd, WM_CLOSE, 0, 0);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_CREATE:
    SHMENUBARINFO mbi;
    // HMENU hMenu; memset(&mbi, 0, sizeof(SHMENUBARINFO));
    mbi.cbSize     = sizeof(SHMENUBARINFO);
    mbi.hwndParent = hWnd;
    mbi.nToolBarId = IDR_MENU;
    mbi.hInstRes   = g_hInst; if (!SHCreateMenuBar(&mbi)) 
    {
    g_hWndMenuBar = NULL;
    }
    else
    {
    g_hWndMenuBar = mbi.hwndMB; } // 初始化外壳程序激活信息结构
    memset(&s_sai, 0, sizeof (s_sai));
    s_sai.cbSize = sizeof (s_sai);
    break;
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... EndPaint(hWnd, &ps);
    break;
    case WM_DESTROY:
    CommandBar_Destroy(g_hWndMenuBar);
    PostQuitMessage(0);
    break; case WM_ACTIVATE:
    // 向外壳程序通知我们的激活消息
    SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
    break;
    case WM_SETTINGCHANGE:
    SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }
    我觉得About对话框的窗口类和主对话框的类差不多么,唯一可以改的就是可以在About CALLBACK函数里添加:
    default:
    return DefWindowProc(hDlg, message, wParam, lParam);//把主函数里DefWindowProc的参数hWnd改成了hDlg
    结果还是没用么。
    还有就是Defwindowproc不是win32的缺省消息处理函数么?我就不明白怎么个调用DefWindowProc法呢?在哪里添加调用的代码呢?
    难道调用了DefWindowProc就能hButton = GetDlgItem(hDlg,IDC_Photo);获得句柄了吗?
      

  4.   

    DialogBox出来的对话框,很搓
      

  5.   

    你说的“唯一”可不对。没看到主对话框的显示用的不是DialogBox吗
      

  6.   

    请问,我在About函数过程中添加case WM_LBUTTONDOWN: 就是为了截取鼠标单击的消息,然后处理。如果我调用了DefWindowProc让系统来调用WM_LBUTTONDOWN不就等于让系统自己处理鼠标单击的消息了么?那我还怎么实现单击图片控件的功能呢?
    再说了我现在的问题是hButton = GetDlgItem(hDlg,IDC_Photo);hButton = NULL;如果我调用DefWindowProc的话,就能获得句柄了吗?
      

  7.   

    在PC下,对话框不需要显式的调用DefWindowProc
    不想交给默认过程处理就返回TRUE即可,交给想交给默认过程就返回FALSE
    移动设备里就不太清楚了,没实际做过没有发言权,我觉得你换个控件ID试下看是否还是NULL?
      

  8.   

    你为什么非要在About窗口里面搞?很不和谐
      

  9.   

    To biweilun :  朋友,我试过了,用CreateWindow来创建窗口,好烦哦,首先还要注册一个窗口类,然后才能用CreateWindow创建函数。而且Create出来的窗口什么都没有,本来我在窗口资源拖入的Picture Control控件也没有了。是一个空白的窗口。是不是CreateWindow出来的窗都要自己调用WM_PAINT消息,在消息中自己绘图界面啊?而不像DialogBox,只要原来在Dialoge资源窗口中拖入一些控件,做好样式,然后DialogBox一下就可以了吗?To hurryboylqs:
      
      谢谢!朋友,我修改了一下控件的ID,添加了一个Button,然后hButton = GetDlgItem(hDlg,IDC_BUTTON1);
      这回得到句柄了。谢谢!看来是第二个参数的问题。谢谢!
      

  10.   

    呵呵,我刚刚自己用VC2008写了个程序,Picture的句柄能取到。要不我程序发你?
      

  11.   


    // “关于”框的消息处理程序。
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
    return (INT_PTR)TRUE;    case WM_LBUTTONDOWN:
                HWND hPhoto; 
                hPhoto= GetDlgItem(hDlg,IDC_PHOTO1); //可以得到
                
            return (INT_PTR)TRUE;
           break;
    case WM_COMMAND:
    if (LOWORD(wParam) == IDOK)
    {
        HWND hPhoto; 
                hPhoto= GetDlgItem(hDlg,IDC_PHOTO1);  //也可以得到
                return (INT_PTR)TRUE;
    }
    if(LOWORD(wParam) == IDCANCEL)
    {
    EndDialog(hDlg, LOWORD(wParam));
    return (INT_PTR)TRUE;
    }
    break;
    }
    return (INT_PTR)FALSE;
    }
      

  12.   

    To biweilun:   谢谢!我重新添加了一个Picture Control控件,把ID改了一下,然后安了一下回车。结果就能获得句柄了。晕!
       还有就是后来我看了原来的Picture Control控件IDC_Photo的定义,发现它的值是-1。这是什么原因?现在的问题是:
    hButton = GetDlgItem(hDlg,IDC_PhotoButton);
    if(NULL == hButton)
    {
    MessageBox(NULL, _T("hButton = NULL"), _T("命令"), MB_OK);

    }
    if(FALSE == GetWindowRect(hButton,&rect))
    {
    MessageBox(NULL, _T("GetWindowRect(hButton,&rect)) = FALSE"), _T("命令"), MB_OK); 
    }

    if(0 == GetCursorPos(&point))
    {
    MessageBox(NULL, _T("GetCursorPos(&point) = ZERO"), _T("命令"), MB_OK);
    LPVOID lpMsgBuf;   
        FormatMessage(     
    FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
    FORMAT_MESSAGE_FROM_SYSTEM   |     
    FORMAT_MESSAGE_IGNORE_INSERTS,   
    NULL,   
    GetLastError(),   
    0,     
    (LPTSTR)&lpMsgBuf,   
    0,   
    NULL);   
        MessageBox(NULL, (LPCTSTR)lpMsgBuf, L"命令", MB_OK | MB_ICONINFORMATION);   
        LocalFree(lpMsgBuf);
    }
    if(FALSE == ScreenToClient(hDlg,&point))
    {
    MessageBox(NULL, _T("ScreenToClient(hDlg,&point) = FALSE"), _T("命令"), MB_OK);
    }
    if(PtInRect(&rect,point))   
    {   
    MessageBox(NULL, _T("在本示范程序中,该命令的功能暂时缺省。"), _T("命令"), MB_OK); 
    }
    else
    {
    MessageBox(NULL, _T("**************"), _T("命令"), MB_OK);
    }
    问题:GetCursorPos=0,是为什么呀?
    我执行了程序以后,发现:
    首先出现:GetCursorPos(&point) = ZERO
    其次GetLastError()
    又是出现:此函数仅在Win32模式下有效。
    这是为什么呢?
      

  13.   

    微软又一个 http call的 例子 就是直接 call dialog的
    你去 see see
      

  14.   

    知道原因了,因为WinCE下不能用GetCursorPos(),而要用GetMessagePos()。