这里先介绍下wParam和lParam,对于鼠标而言,LOWORD(wParam)和HIWORD(wParam)代表鼠标位置x,y坐标,对于菜单和控件而言,两者wParam的低字节都是各自的ID,即LOWORD(wParam)都是ID。两者的高字节对菜单而言是0,对控件而言是消息码(消息码也可能是0)所以不能单凭wParam参数来判断消息是来自于菜单还是来自于控件,但是可以通过lParam来判断,对于菜单而言lParam恒为0,而对于控件而言却是子窗口句柄。因此就可以这样判断:
case WM_COMMAND: { if(lParam == 0) { //code 处理菜单ID, } else { //code 处理控件ID } }
现在开始介绍对话框(*^__^*)
模式对话框和无模式对话框:无模式对话框允许我们把输入焦点切换到同一个应用程序的另一个窗口,该对话框也无需关闭,这个比较普遍。可以用API函数CreateDialogParam创建。
模式对话框主要是两类:应用程序模式对话框和系统对话框。应用程序对话框不允许我们在本应用程序中切换输入焦点,但是可以切换到其他应用程序中去,比如点击记事本的文件打开按钮,会弹出选择打开文件的对话框,这个对话框不能切换到记事本中,但是可以切换到其他应用程序中去。这个就是属于应用程序模式对话框。系统对话框则比较恶毒,不允许你切换到任何一个应用程序中,我们一看名字就知道,系统对话框,看似比较紧急,要求我们必须首要解决····模式对话框可以用API函数DialogBoxParam产生。
首先了解下窗口过程处理函数
对话框过程处理函数格式为: BOOL CALLBACK DialogProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);返回值是TURE和FALSE,是BOOL类型。在windows头文件里是int类型。
窗口过程处理函数格式为:LRESULT CALLBACK ProcWinMain( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);返回值是LRESULT。
如果窗口过程函数不处理某个消息,那么就会调用DefWindowProc;但是如果对话框过程处理一个消息就返回TRUE,如果不处理就返回FALSE(0)。这里还要注意的是对话框过程不处理WM_PAINT或者WM_DESTORY消息,对话框也不接受WM_CREATE消息。代替MW_CREATE消息的是WM_INITDIALOG,对话框过程执行初始化。此外,对话框过程只处理WM_COMMAND消息,对于鼠标点击等wParam的低位字节就是控件的ID。关于结束对话框,对话框过程处理函数只接受WM_EndDialog消息,它来告诉windows清除对话框。对于其他消息都返回FALSE。
下面介绍一种对话框产生的方法:(把对话框当作窗口来处理)
RegisterClassEx函数把对话框模板注册为一个窗口类,然后创建一个由该窗口类派生的窗口。修改的地方是stdWndClass.cbWndExtra,原本都是NULL,现在改成DLGWINDOWEXTRA。如下
stdWndClass.cbWndExtra = DLGWINDOWEXTRA;
stdWndClass.lpszClassName = ClassName;
stdWndClass.cbClsExtra = NULL;
这里要注意stdWndClass.lpszClassName对应的是窗口类的名字。这样才能把对话框当作是窗口进行处理。
改好之后照常调用函数RegisterClassEx注册窗口类
接着就是hDlg=CreateDialogParam(hInstance,DlgName,NULL,NULL,NULL);
非模态对话框对消息的处理都是要进过程序的消息队列的,也就是处理的时候都是要进过程序窗口过程的处理。
最后就是在消息循环里面的改进:(IsDialogMessage判断消息是否为对话框消息,用CreateDialogParam创建非模式对话框则需要)
while(GetMessage(&stMsg,NULL,0,0))
{
if(
!IsDialogMessage(hDlg,&stMsg)
)
{
下面介绍我当时的一个失误:
我最初用VC6.0以窗口的形式创建一个对话框,结果出现了一个问题,就是对话框是生成了,但就是关不了。我连点击右上角的关闭按钮也不行,我看了下资源文件,结果发现比正常的资源文件对话框那块少了句CLASS"DLGCLASS1"(“”里面的是窗口类的名字,我这里是我自己窗口类的名字)要是没有这一句就不能把对话框当作窗口来用,我们就不能进行任何操作。后来我发现是我引进资源的时候出了问题,我在资源文件对应的地方加了这句就可以了。
下面是资源文件的对话框部分:.rsrc.rc部分
MYDIALOG DIALOG DISCARDABLE 0, 0, 187, 96
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Our First Dialog Box"
FONT 10, "System"
CLASS "DLGCLASS1" //这一句非常重要
BEGIN
PUSHBUTTON "exit",IDC_EXIT,17,16,48,23
EDITTEXT IDC_EDIT,81,20,84,43,ES_AUTOHSCROLL
END
下面是源文件:
#include "Windows.h"
#include "tchar.h"
#include "resource.h"
TCHAR ClassName[] = _T("DLGCLASS1");
TCHAR DlgName[] = _T("MyDialog");
TCHAR AppName[] = _T(" Dialog Box");
HINSTANCE g_hInstance;
LRESULT CALLBACK ProcWinMain( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
switch(Msg)
{
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_EXIT:
SendMessage(hWnd,WM_DESTROY,0,0);
break;
}
}
break;
case WM_DESTROY:
{
PostQuitMessage(NULL);
}
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam );
}
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
HICON hIcon;
HCURSOR hCursor;
MSG stMsg;
WNDCLASSEX stdWndClass;
HWND hDlg;
g_hInstance = hInstance;
RtlZeroMemory(&stdWndClass, sizeof(stdWndClass));
stdWndClass.hCursor = LoadCursor(0,IDC_ARROW);
stdWndClass.cbSize = sizeof(stdWndClass);
stdWndClass.style = CS_HREDRAW|CS_VREDRAW;
stdWndClass.lpfnWndProc = ProcWinMain;
stdWndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
stdWndClass.lpszClassName = ClassName;
stdWndClass.hInstance = hInstance;
stdWndClass.cbClsExtra = NULL;
stdWndClass.cbWndExtra = DLGWINDOWEXTRA;
hIcon = LoadIcon(NULL,IDI_APPLICATION);
stdWndClass.hIcon = hIcon;
stdWndClass.hIconSm = hIcon;
hCursor = LoadCursor(NULL,IDC_ARROW);
stdWndClass.hCursor = hCursor;
RegisterClassEx(&stdWndClass);
hDlg = CreateDialogParam(hInstance,DlgName,NULL,NULL,NULL);
if(!hDlg)
return 0;
ShowWindow(hDlg,SW_SHOWNORMAL);
UpdateWindow(hDlg);
while(GetMessage(&stMsg,NULL,0,0))
{
if(!IsDialogMessage(hDlg,&stMsg))
{
TranslateMessage(&stMsg);
DispatchMessage(&stMsg);
}
}
return stMsg.wParam;
}
上面的做的很简单,我就是列举了一些注意点。才看了几天,也许有比较多的错误,希望指点。(*^__^*)