C++图形用户界面编程(2)

来源:互联网 发布:git安装教程mac 编辑:程序博客网 时间:2024/06/05 09:16

上一篇文章就创建了一个简单的窗口,这次在窗口上添加个控件,做的比较简单,但东西都包含在内了。

这就是界面了,有两个编辑框,一个按钮。按下按钮,会弹出一个对话框,提示按钮按下。上面那个小编辑框可以输入字符,输入后按下回车,就会把输入的字符显示到下面的大编辑框中。代码如下:

#include <windows.h>LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);LRESULT CALLBACK EditProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);HWND hwnd;HWND hwndButton,hwndEdit,hwndLable;WNDPROC OldEditProc;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){MSG messages;WNDCLASSEX wcx;wcx.cbSize=sizeof(wcx);wcx.style=CS_HREDRAW|CS_VREDRAW;//窗口样式wcx.lpfnWndProc=MainWndProc;//消息处理函数wcx.cbClsExtra=0;//指定紧跟在窗口类结构后的附加字节数wcx.cbWndExtra=0;//指定紧跟在窗口实例的附加字节数wcx.hInstance=hInstance;//本模块的实例句柄wcx.hIcon = LoadIcon (NULL, IDI_APPLICATION);//图标的句柄wcx.hCursor = LoadCursor (NULL, IDC_ARROW);//光标的句柄wcx.hbrBackground = (HBRUSH) COLOR_MENU;//背景画刷的句柄wcx.lpszMenuName = NULL;//指向菜单的指针wcx.lpszClassName="test";//要注册窗口类的类名wcx.hIconSm = LoadIcon( NULL, IDI_WINLOGO );//和窗口类关联的小图标if (!RegisterClassEx (&wcx)){return 0;}hwnd = CreateWindowEx (NULL,"test",//之前注册的窗口类"hello", //窗口名WS_OVERLAPPED|WS_SYSMENU|WS_VISIBLE,//窗口样式CW_USEDEFAULT,//窗口创建后的水平初始位置CW_USEDEFAULT,//窗口创建后的垂直初始位置550,//窗口宽度350,//窗口高度HWND_DESKTOP,//指向被创建窗口的父窗口或所有者窗口的句柄。HWND_DESKTOP系统自定义的最顶层托管窗口。NULL,//菜单句柄hInstance,//与窗口相关联的模块实例的句柄NULL);//指向一个值的指针,该值传递给窗口WM_CREATE消息if (!hwnd){return 0;}//添加按钮hwndButton=CreateWindowEx(NULL,TEXT("BUTTON"),TEXT("按钮"),WS_CHILD|WS_VISIBLE|BS_NOTIFY,400,20,50,20,hwnd,(HMENU)1,hInstance,NULL);//添加编辑框hwndEdit=CreateWindowEx(NULL,TEXT("EDIT"),TEXT(""),WS_CHILD|WS_VISIBLE|WS_BORDER|BS_TEXT,140,20,200,20,hwnd,(struct HMENU__ *)0,hInstance,NULL);hwndLable=CreateWindowEx(NULL,TEXT("EDIT"),TEXT(""),WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE|ES_READONLY,20,70,495,230,hwnd,(struct HMENU__ *)0,hInstance,NULL);//定制编辑框控件消息处理函数OldEditProc=(WNDPROC)SetWindowLong (hwndEdit, GWL_WNDPROC, (LONG)EditProcedure);ShowWindow (hwnd, nShowCmd);while (GetMessage (&messages, NULL, 0, 0)){TranslateMessage(&messages);DispatchMessage(&messages);}return messages.wParam;}LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch(message){case WM_CREATE://窗口创建时收到此消息break;case WM_PAINT://窗口被绘制时收到此消息break;case WM_SIZE://窗口大小改变时收此消息break;case WM_NOTIFY://通常由控件发给其父窗口,说明控件正在进行某项窗口操作break;case WM_DESTROY://窗口销毁时或点击关闭收到此消息PostQuitMessage(0);break;case WM_COMMAND://命令输入,菜单项{//if (LOWORD(wParam)==0&&HIWORD(wParam)==BN_DOUBLECLICKED)if (LOWORD(wParam)==1&&HIWORD(wParam)==BN_CLICKED){MessageBox(hwnd,TEXT("按钮按下啦..."),TEXT("提示"),MB_OK);}}default:break;}//有很多消息未作处理,需要有默认窗口消息处理函数来处理return DefWindowProc (hwnd, message, wParam, lParam);}LRESULT CALLBACK EditProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_CHAR:{if (wParam==VK_RETURN)//回车键{char *szBuff=new char[10];ZeroMemory(szBuff,10);GetWindowText(hwndEdit,szBuff,10);SendMessage (hwndLable, EM_REPLACESEL, 0, (LPARAM) szBuff);delete [] szBuff;}CallWindowProc(OldEditProc,hwnd,message,wParam,lParam);}break;default:                    return CallWindowProc(OldEditProc,hwnd,message,wParam,lParam);break;}return 0;}

    可见创建控件也是用CreateWindowEx函数,和创建窗口不同的是,创建控件不用注册,因为系统已经注册好了,我们直接用就可以,比如按钮直接用BUTTON,编辑框用EDIT等。创建控件倒数第三个参数是控件ID,在处理控件消息是会用到。控件上发生动作时,将向父窗口发送通知消息WM_COMMAND。

    控件的消息处理函数是由系统定义好了的,通常情况下,不需要自己提供。但当需要对控件进行特殊控制时,可以提供一个消息处理函数,替换原来的消息处理函数。自己的处理完成后,再调用控件的缺省消息处理。比如上面要响应编辑框的回车消息,我们就需要自己写消息处理函数了,步骤如下:

1.提供新处理函数

//记录原来处理函数的全局变量

WNDPROC OldMsgProc;

2.建立窗口后,更改消息处理函数

HWND hControlWnd = CreateWindowEx(0,"BUTTON",

         TEXT("按钮(&A)"),

         WS_CHILD | WS_VISIBLE|BS_PUSHBUTTON,

         10,

         10,

         100,

         100,

         hwnd,

         (HMENU)1000,  //控件ID

         ((LPCREATESTRUCT) lParam)->hInstance, //实例句柄

         NULL);

 

     //嵌入新的消息处理函数

     OldMsgProc = (WNDPROC) SetWindowLong (hControlWnd, GWL_WNDPROC, (LONG)MyMsgProc);

3 编写新消息处理函数

//新消息处理函数

LRESULT MyMsgProc(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam)

{

     switch(message)

     {

     case XXXX:

         .................

     }

     //调用控件原来的消息处理函数

     return CallWindowProc(OldMsgProc,hwnd,message,wParam,lParam);

}

    这样就可以啦。控件以及窗口间发送消息直接调用SendMessage即可,比如代码中SendMessage (hwndLable, EM_REPLACESEL, 0, (LPARAM) szBuff),就向编辑框发了个EM_REPLACESEL消息,EM_REPLACESEL消息处理函数系统已经写好了,我们只管发送就行了。

    关于wParam和 lParam,控件上发生动作时,将向父窗口发送通知消息WM_COMMAND。WM_COMMAND的HIWORD(wParam)代表通知码,LOWORD(wParam)代表控件ID,(HWND)lParam:表示控件句柄。针对不同消息,wParam,lParam代表不同意义,WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递。

    如果自定义消息,需确定wParam,lParam的意义,(假设wParam=0时发送数据,wParam=1时接收数据,lParam为CMyClass* 指针,指向一个CMyClass对象,准备要发送的数据或接收数据。发送WM_MYMESSAGE时 SendMessage(hwnd,WM_MYMESSAGE,0,pMyClassObject),接收消息的窗口,接收WM_MYMESSAGE中(CMyClass*)lParam参数即pMyClassObject传过来的数据。

0 0
原创粉丝点击