Win32下 GetDlgItem返回空

jay_lee_1982 2009-05-17 01:36:05
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模式下有效。
...全文
376 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
jay_lee_1982 2009-05-19
  • 打赏
  • 举报
回复
知道原因了,因为WinCE下不能用GetCursorPos(),而要用GetMessagePos()。
jay_lee_1982 2009-05-18
  • 打赏
  • 举报
回复
不要支持啊,大哥!我想知道问题怎么解决?
jay_lee_1982 2009-05-18
  • 打赏
  • 举报
回复
有用么?我现在想知道得,只是我自己得程序问题在哪里而已。谢谢!
金金2019 2009-05-18
  • 打赏
  • 举报
回复
微软又一个 http call的 例子 就是直接 call dialog的
你去 see see
biweilun 2009-05-17
  • 打赏
  • 举报
回复
你为什么非要在About窗口里面搞?很不和谐
hurryboylqs 2009-05-17
  • 打赏
  • 举报
回复
在PC下,对话框不需要显式的调用DefWindowProc
不想交给默认过程处理就返回TRUE即可,交给想交给默认过程就返回FALSE
移动设备里就不太清楚了,没实际做过没有发言权,我觉得你换个控件ID试下看是否还是NULL?
jay_lee_1982 2009-05-17
  • 打赏
  • 举报
回复
请问,我在About函数过程中添加case WM_LBUTTONDOWN: 就是为了截取鼠标单击的消息,然后处理。如果我调用了DefWindowProc让系统来调用WM_LBUTTONDOWN不就等于让系统自己处理鼠标单击的消息了么?那我还怎么实现单击图片控件的功能呢?
再说了我现在的问题是hButton = GetDlgItem(hDlg,IDC_Photo);hButton = NULL;如果我调用DefWindowProc的话,就能获得句柄了吗?
biweilun 2009-05-17
  • 打赏
  • 举报
回复
你说的“唯一”可不对。没看到主对话框的显示用的不是DialogBox吗
biweilun 2009-05-17
  • 打赏
  • 举报
回复
DialogBox出来的对话框,很搓
jay_lee_1982 2009-05-17
  • 打赏
  • 举报
回复
这是主对话框程序:
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);获得句柄了吗?
biweilun 2009-05-17
  • 打赏
  • 举报
回复
在你的主对话类中

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);
按主对话框的类照猫画虎就行了
TCLTV 2009-05-17
  • 打赏
  • 举报
回复
支持
jay_lee_1982 2009-05-17
  • 打赏
  • 举报
回复
对的。很头痛!!!
biweilun 2009-05-17
  • 打赏
  • 举报
回复
GetCursorPos不行?
jay_lee_1982 2009-05-17
  • 打赏
  • 举报
回复
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模式下有效。
这是为什么呢?
蒋晟 2009-05-17
  • 打赏
  • 举报
回复
为什么不调用DefWindowProc?这是必须的。
biweilun 2009-05-17
  • 打赏
  • 举报
回复

// “关于”框的消息处理程序。
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;
}


biweilun 2009-05-17
  • 打赏
  • 举报
回复
呵呵,我刚刚自己用VC2008写了个程序,Picture的句柄能取到。要不我程序发你?
jay_lee_1982 2009-05-17
  • 打赏
  • 举报
回复
To biweilun :

朋友,我试过了,用CreateWindow来创建窗口,好烦哦,首先还要注册一个窗口类,然后才能用CreateWindow创建函数。而且Create出来的窗口什么都没有,本来我在窗口资源拖入的Picture Control控件也没有了。是一个空白的窗口。是不是CreateWindow出来的窗都要自己调用WM_PAINT消息,在消息中自己绘图界面啊?而不像DialogBox,只要原来在Dialoge资源窗口中拖入一些控件,做好样式,然后DialogBox一下就可以了吗?

To hurryboylqs:

谢谢!朋友,我修改了一下控件的ID,添加了一个Button,然后hButton = GetDlgItem(hDlg,IDC_BUTTON1);
这回得到句柄了。谢谢!看来是第二个参数的问题。谢谢!

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧