Win32界面程序
目录 一、Windows编程基础知识... 1 1.句柄... 1 2.消息... 1 (1)系统定义的消息分类... 2 (2)不同消息的取值范围... 2 (3)Windows应用中的常用消息... 2 二、Windows应用的基本结构... 3 1.数据类型... 3 2.数据结构... 4 (1)MSG.. 4 (2)WNDCLASSEX.. 4 (3)POINT. 5 (4)RECT. 5 3.入口函数WinMain() 6 (1)参数说明... 6 (2)定义窗口类... 6 (3)注册窗口类... 6 (4)创建窗口... 7 (5)显示窗口... 8 (6)消息循环... 9 4.处理函数... 9 三、图形绘制... 10 1.设备描述表(Device Context,DC) 10 2.设备描述表的默认属性和相关函数... 10 3.图形刷新的办法... 13 (1)对于简单的图形重新绘制即可... 13 (2)对于位图等复杂图形需要在内存中保存一个副本,重绘窗口的时候再将副本输出... 13 (3)记录曾经发生过的事件,窗口刷新的时候重新执行这个事件... 13 4.常用绘图函数... 13 (1)设置画笔当前位置的函数MoveToEx() 13 (2)从当前位置到指定位置画线的函数LineTo. 13 (3)绘制椭圆弧线的函数Arc,从起始点逆时针到终止点的曲线... 14 (4)画一个饼并用当前画刷进行填充的函数Pie(),从起始径线逆时针到终止径线扫过地扇形... 14 (5)绘制一个矩形,并用当前画刷进行填充的函数Rectangle() 14 (6)绘制一个圆角矩形,并用当前画刷填充的函数RoundRect() 15 (7)绘制一个椭圆,并用当前画刷填充的函数Ellipse() 15 (8)绘制一个多边形,并用当前画刷进行填充的函数Polygon() 15 5.图形绘制的一般步骤... 16 (1)获取设备环境... 16 (2)映射模式... 16 (3)使用绘图工具和颜色... 19 四、文字输出和字体设置... 21 1.选择字体... 21 2.设置字体颜色... 23 3.文本输出... 23 4.删除字体... 25 五、键盘和鼠标... 25 1.键盘消息... 25 (1)wParam中的虚拟码... 25 (2)插字符... 26 2.鼠标消息... 26 (1)不同样式的光标... 26 (2)常用的鼠标消息... 27 (3)鼠标消息中的字参数和长字参数... 27 六、程序的资源... 28 1.菜单资源... 28 (1)定义菜单... 28 (2)加载菜单资源... 29 (3)操作菜单项... 29 2.加速键资源... 31 (1)定义加速键资源... 31 (2)载入加速键资源... 32 (3)翻译加速键... 32 3.位图资源... 32 (1)定义位图资源... 32 (2)初始化... 33 (3)输出位图... 34 4.对话框资源... 36 (1)模式对话框... 36 (2)Windows消息框MessageBox. 38 (3)非模式对话框... 40 5.图标资源... 41 七、Windows标准控件... 41 1.静态控件... 41 2.按钮... 41 (1)创建方法... 41 (2)按钮的样式... 41 3.列表框... 42 (1)创建方法... 42 (2)常用属性... 42 4.滚动条... 42 (1)创建方法... 42 5.编辑框... 42 (1)创建方法... 42 (2)常用属性... 42 6.组合框... 42 (1)创建方法... 42 八、单文档与多文档... 42 1.CC++多线程... 42 九、附录... 43 1.应用程序的发布... 43 2.参考网址... 43 正文 一、Windows编程基础知识Windows程序根据事件或消息的不同驱动运行处理函数Proc,这个过程叫做事件驱动 1.句柄句柄是用于唯一标识对象的PVOID数据、一个4字节长的数值,通过句柄能够访问对象的信息
2.消息作用是信息交换,由消息号UINT、字参数wParam、长字参数lParam,长字参数和具体消息的附加信息有关,比如: typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; //这个消息到队列的时间 DWORD time; //消息产生时,屏幕光标的位置,横坐标x、纵坐标y POINT pt; }MSG; (1)系统定义的消息分类
(2)不同消息的取值范围
(3)Windows应用中的常用消息①WM_LBUTTONDOWN 点击鼠标左键会触发这个消息,字参数wParam表示鼠标的单击状态,长字参数lParam的低字节表示当前光标的x坐标、高字节表示当前光标的y坐标;和WM_LBUTTONDOWN类似的消息还有松开鼠标左键WM_LBUTTONUP、点击鼠标右键WM_RBUTTONDOWN、松开鼠标右键WM_RBUTTONUP、双击鼠标左键WM_LBUTTONBLCLK、双击鼠标右键WM_RBUTTONDBLCLK。
②WM_KEYDOWN 按下非系统控制键时产生的消息,非系统键指不是系统内置的键,类似消息有松开非系统键产生的消息WM_KEYUP;字参数wParam表示按下或释放的键,长字参数lParam表示按键的重复次数等信息;VK_END、VK_HOME、VK_DELETE、VK_LEFT、VK_RIGHT、VK_UP、VK_DOWN ③WM_CHAR 也是按下非系统键产生的消息,wParam表示按键的ASCII码值、lParam表示重复次数等信息,VK_BACK、VK_RETURN ④WM_CREATE 由CreateWindow()触发,wParam未使用、lParam是一个指向数据结构CREATESTRUCT的指针,修改这个结构体就可以在创建窗口的时候给CreateWindow()传递参数 ⑤WM_CLOSE 窗口关闭时产生的消息 ⑥WM_DESTROY 由DestroyWindow()触发 ⑦WM_QUIT 由PostQuitMessage()触发,wParam表示程序退出时的有关信息,lParam未使用 ⑧WM_PAINT 窗口的显示状态发生变化的时候触发,比如窗口位置、大小发生变化等情况会触发WM_PAINT消息 ⑨WM_COMMAND 和用户定义的控件ID有关的消息,也包括一些内置消息IDOK、IDCANCEL 二、Windows应用的基本结构Windows项目中可能会遇到这几种类型的文件,.cpp程序的源文件、.h头文件、.def模块定义文件、.rc资源描述文件 1.数据类型
2.数据结构(1)MSG消息的结构体,包含消息必要的信息 (2)WNDCLASSEX一个窗口类的全部信息,通过结构体可以修改一个窗口类的属性信息 Typedef struct { //结构体的大小,通常取sizeof(WNDCLASSEX) UINT cbSize; //窗口类的样式,一般设为0 UINT style; //指向处理函数的指针 WNDPROC lpfnWndProc; //分配给窗口类的额外字节数 int cbClsExtra; //分配给窗口实例的额外字节数 int cbWndExtra; //窗口类的实例句柄 HANDLE hInstance; //图标 HICON hIcon; //光标样式 HCURSOR hCursor; //背景笔刷 HBRUSH hbrBackground; //菜单资源的名字 LPCTSTR lpszMenuName; //窗口类的名字 LPCTSTR lpszClassName; //小图标,暂不知道差别在哪里,小图标和图标的取值一样 HICON hIconSm; }WNDCLASSEX; (3)POINTtypedef struct tagPOINT { LONG x; LONG y; }POINT; (4)RECT矩形区域 typedef struct _RECT { //矩形框左上角的x坐标值 LONG left; //矩形框左上角的y坐标值 LONG top; //矩形框右下角的x坐标值 LONG right; //矩形框右下角的y坐标值 LONG bottom; }RECT; 3.入口函数WinMain()(1)参数说明
(2)定义窗口类给结构体WNDCLASSEX特定的属性值,可能会用到的函数: 添加特定的图标 HICON LoadIcon( //需要设置图标的对象的句柄,设置为NULL可能会快些 HINSTANCE hInstance, //图标的名字 LPCTSTR lpIconName); 设置窗口的光标 HCURSOR LoadCursor( //需要设置光标的对象的句柄,设置为NULL可能会快些 HINSTANCE hInstance, //光标的名字 LPCTSTR lpCursorName); 设置窗口背景 HBRUSH GetStockObject( //笔刷的名字 int nBrush); (3)注册窗口类//如果注册成功返回值为真TRUE BOOL RegisterClassEx(WNDCLASSEX&); (4)创建窗口GetSystemMetrics (SM_CXSCREEN)获取全屏的宽度、GetSystemMetrics (SM_CYSCREEN)获取全屏的高度,类似的有SM_CXFULLSCREEN、不含任务栏;LOWORD(GetDialogBaseUnits())得到x方向的相对长度、HIWORD(GetDialogBaseUnits())得到y方向的相对长度 CreateWindow函数 HWND CreateWindow( //窗口类的名字 LPCTSTR lpszClassName, //窗口标题的名字 LPCTSTR lpszTitle, //窗口的样式 DWORD dwStyle, //窗口左上角的x坐标 int x, //窗口左上角的y坐标 int y, //窗口的宽度 int nWidth, //窗口的高度 int nHeight, //当前窗口的父窗口句柄 HWND hwndParent, //当前窗口的主菜单句柄 HMENU hMenu, //当前应用程序的实例句柄 HINSTANCE hInstance, //传递给窗口的参数值的指针 LPVOID lpParam); 窗口常用样式 多个样式通过位或运算组合成窗口的样式
(5)显示窗口ShowWindow函数将窗口显示在屏幕上 BOOL ShowWindow( //窗口句柄 HWND hwnd, //显示形式的标识 int nCmdShow); UpdateWindow函数更新窗口 UpdateWindow(HWND hwnd); 显示样式的标识
(6)消息循环Windows产生的消息将放到程序的消息队列中,程序将消息取出并传递给处理函数 //从消息队列中取出一条消息放大MSG类型的结构中,最后两个参数表示过滤的最小消息号、过滤的最大消息号,都为0表示不过滤 //当取到WM_QUIT消息时程序退出循环 While(GetMessage(MSG&,NULL,0) { //将虚拟键转换为字符信息 TranslateMessage(MSG&); //将消息传递给制定的处理函数 DispatchMessage(MSG&); } 4.处理函数LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { switch (message) { case ...: ...; break; ... case WM_DESTROY: PostQuitMessage (0); break; default: //我们不处理的消息交给系统以默认方式处理 return DefWindowProc (hwnd,message,wParam,lParam); } return 0; } 三、图形绘制Windows图形设备接口GDI屏蔽了硬件设备的差异,分担了程序的硬件设备适配器的功能;SetTimer()设置定时器,可以按照一定的时间间隔“提醒”某个窗口,从而得到动态的效果对应的事件是WM_TIMER、计时器的编号和wParam有关、KillTimer()将销毁一个定时器 1.设备描述表(Device Context,DC)
2.设备描述表的默认属性和相关函数
3.图形刷新的办法用户区移动或显示、用户区窗口大小发生改变、程序通过滚动条滚动窗口、下拉式菜单关闭后需要恢复被覆盖的部分、光标穿过用户区、图标拖过用户区都会导致图形的显示状态发生改变时,Windows系统将发送WM_PAINT消息给应用程序 (1)对于简单的图形重新绘制即可InvalidateRect(hwnd,TRUE); (2)对于位图等复杂图形需要在内存中保存一个副本,重绘窗口的时候再将副本输出(3)记录曾经发生过的事件,窗口刷新的时候重新执行这个事件4.常用绘图函数(1)设置画笔当前位置的函数MoveToEx()BOOL MoveToEx( HDC hdc, //最新位置 int x, int y, //原位置的POINT结构体指针 LPPOINT lpPoint); (2)从当前位置到指定位置画线的函数LineToBOOL LineTo(HDC hdc,int x,int y); 从当前位置开始依次连接各点 BOOL Polyline( HDC hdc, //POINT结构体数组的指针 LPPOINT lpPoints, //数组中元素的个数 Int nCount); (3)绘制椭圆弧线的函数Arc,从起始点逆时针到终止点的曲线BOOL Arc( HDC hdc, //边框矩形左上角的逻辑坐标 int x1,int y1, //边框矩形右下角的逻辑坐标 int x2,int y2, //起始点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用) int x3,int y3, //终止点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用) int x4,int y4); (4)画一个饼并用当前画刷进行填充的函数Pie(),从起始径线逆时针到终止径线扫过地扇形BOOL Pie( HDC hdc,int y4); (5)绘制一个矩形,并用当前画刷进行填充的函数Rectangle()BOOL Rectangle( HDC hdc, //矩形左上角的逻辑坐标 int x1, //矩形右下角的逻辑坐标 int x2,int y2); (6)绘制一个圆角矩形,并用当前画刷填充的函数RoundRect()BOOL RoundRect( HDC hdc, //圆角的宽度 int nWidth, //圆角的高度 int nHeight); (7)绘制一个椭圆,并用当前画刷填充的函数Ellipse()BOOL Ellipse( HDC hdc, //边界矩形左上角的逻辑坐标 int x1, //边界矩形右下角的逻辑坐标 int x2,int y2); (8)绘制一个多边形,并用当前画刷进行填充的函数Polygon()BOOL Polygon( HDC hdc, //数组中元素的个数 int nCount); 5.图形绘制的一般步骤(1)获取设备环境①响应WM_PAINT消息,对无效区域进行刷新 HDC BeginPaint(HWND,PAINTSTRUCT&); BOOL EndPaint(HWND,PAINTSTRUCT&); 结构体PAINTSTRUCT typedef struct tagPAINTSTRUCT { //设备环境句柄 HDC hdc; //一般取真TRUE,表示擦除无效矩形的阴影 BOOL fErase; //无效矩形 RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; ②独立于WM_PAINT消息的刷新 //也可以使用GetDCEx(),它是GetDC()的扩展、提供了更丰富的操作 HDC GetDC(HWND); int ReleaseDC(HWND,HDC); (2)映射模式MM_TEXT是默认的映射模式;对逻辑坐标系的定义(窗口),屏蔽了输出设备的坐标系差异(视口) ① 可选的映射模式
② 设置映射模式 int GetMapMode(HDC); int SetMapMode(HDC hdc,int nMapMode); ③ 设置窗口区域、视口区域 BOOL SetWindowExtEx( HDC hdc, //窗口区域的逻辑高度 int nHeight, //窗口区域的逻辑宽度 int nWidth, //调用前窗口区域的SIZE结构体的地址,取NULL将忽略之前的尺寸 LPSIZE lpSize); 设置视口区域 BOOL SetViewportExtEx( HDC hdc, /视口区域的物理高度 int nHeight, //视口区域的物理宽度 int nWidth, //调用前窗口区域的SIZE结构体的指针,取NULL将忽略之前的尺寸 LPSIZE lpSize); ④ 当映射模式是MM_ANISOTROPIC或者MM_ISOTROPIC时,可以设置窗口、视口的默认原点 BOOL SetWindowOrgEx( HDC hdc, //窗口原点的最新位置 int x, //调用前窗口原点的POINT结构体的指针,取NULL将忽略之前的尺寸 LPPOINT lpPoint); BOOL SetViewportOrgEx( HDC hdc, //视口原点的最新位置 int x, //调用前视口原点的POINT结构体的指针,取NULL将忽略之前的尺寸 LPPOINT lpPoint); ⑤ 获取用户区的大小 绘制图形的时候可能会参考用户区的大小 BOOL GetWindowRect( //目的窗口句柄 HWND hWnd, //将结果装入RECT结构体的指针中 LPRECT lpRect); BOOL GetClientRect( //用户区的窗口句柄 HWND hWnd, //将结果装入RECT结构体的指针中 LPRECT lpRect); (3)使用绘图工具和颜色①画笔 创建画笔 //使用系统内置的画笔 HPEN hP=(HPEN)GetStockObject(BLACK_PEN); //使用自定义的画笔 HPEN hP=CreatePen( //画笔的样式 int nPenStyle, //画笔的像素宽度,取0表示一个像素宽度 int nWidth, //画笔的颜色 COLORREF rgbColor); 画笔的样式
将画笔置入设备环境 //hPenOld是上一次使用的画笔 HPEN hPenOld=SelectObject(hdc,hP); 删除画笔 //恢复原来的画笔 SelectObject(hdc,hPenOld); //删除画笔 DeleteObject(hP); ②画刷 创建画刷 //使用系统内置的画刷 HBRUSH hBr=(HBRUSH)GetStockObject(int nBrushStyle); 画刷的样式
创建指定颜色的单色画刷 HBRUSH hBr=(HBRUSH)CreateSolidBrush(COLORREF rgbColor); 创建带阴影和颜色的画刷 HBRUSH hBr=(HBRUSH)CreateHatchBrush( //阴影样式 int nHatchStyle, COLORREF rgbColor); 阴影样式
将画刷置入设备环境 //hBrOld是上一次使用的画刷 HBRUSH hBrOld=SelectObject(hdc,hBr); 删除画刷 //恢复原有画刷 SelectObject(hdc,hBrOld); DeleteObject(hBr); ③颜色 画笔用于绘制线条、画刷用于区域填充 Windows使用32位无符号整数表示颜色,从低位到高位依次是蓝、绿、红,各占一个字节(8个bit位) COLORREF RGB(int nRed,int nGreen,int nBlue); 四、文字输出和字体设置由_T(“”)创建字符串常用变量,在VC的环境下默认是unicode字符集的用L(“”)、或者设置为多字节字符集的工程;一个汉字的处理长度是一个英文字母的两倍,字体的选择和超级键+fonts下面的字体有关 1.选择字体使用系统内置的字体 //nFont是字符集可以是ANSI_CHARSET、BALTIC_CHARSET、CHINESEBIG5_CHARSET、DEFAULT_CHARSET、GB2312_CHARSET等 HFONT hf=(HFONT)GetStockObject(int nfont); SelectObject(hdc,hf); 使用自定义的字体 HFONT CreateFont( //字体逻辑高度,取0表示使用系统默认值 Int nHeight //字体逻辑宽度,取0表示使用系统默认值 Int nWidth, //每行文字相对于页底的角度,一个单位表示十分之一度 Int nEscapement, //每个文字相对于页底的角度,一个单位表示十分之一度 Int nOrientation, //字体的粗细,取值是0-1000,400是正常字体700是黑体 Int nWeight, //非零值表示倾斜 DWORD fdwItalic //非零值表示下划线, DWORD fdwUnderline, //非零值表示中划线 DWORD fdwStrikeOout, //字符集 DWORD fdwCharset, //输出精度,一般取OUT_DEFAULT_PRECIS DWORD fdwOutputPrecision, //剪裁精度,一般取CLIP_DEFAULT_PRECIS DWORD fdwClipPrecision, //输出质量,一般取DEFAULT_QUALITY DWORD fdwQuality, //字体间距和字体系列,一般取DEFAULT_PITCH DWORD fdwPitchAndFamily, //字体名,和C:Windowsfonts下面的字体有关 DWORD lpszFacename); 创建全局字体 case WM_CREATE: hdc=GetDC(hwnd); GetTextMetrics(hdc,&tm); nLnHeight=tm.tmHeight+tm.tmExternalLeading; nCharWidth=tm.tmAveCharWidth; CreateCaret(hwnd,nCharWidth/10,tm.tmHeight); ShowCaret(hwnd); ReleaseDC(hwnd,hdc); break; 2.设置字体颜色SetTextColor(hdc,crColor); SetBkColor(hdc,crColor); 3.文本输出从某个位置开始输出 BOOL TextOut( HDC hdc, //字符串的起始坐标 Int x,int y, //字符串 LPCTSTR lpString, //字符串的字符数 Int nCount); 文本输出到一个矩形中 Int DrawText( HDC hdc, //字符串中的字符数 Int nCount, //矩形的指针 LPRECT lpRect, //其他选项 UINT uFormat); 全局字体输出 case WM_PAINT: hdc=BeginPaint(hwnd,&PtStr); for(int i=0; i<=nNumLine; ++i) TextOut(hdc,nLnHeight*i,cCharInfo[i],nArrayPos[i]); SIZE size; GetTextExtentPoint(hdc,cCharInfo[nY],nX,&size); nXCaret=size.cx; nYCaret=nLnHeight*nY; SetCaretPos(nXCaret,nYCaret); EndPaint(hwnd,&PtStr); break; 4.删除字体DeleteObject(hFont); 五、键盘和鼠标1.键盘消息(1)wParam中的虚拟码扫描码是对按键的唯一标识、当按下或释放时扫描码发挥作用,虚拟码用于屏蔽不同设备扫描码的差异;键盘的处理要结合WM_CHAR、WM_KEYDOWN等消息
(2)插字符插字符表示当前文本编辑的位置,就像光标表示当前鼠标的位置一样 创建插字符 BOOL CreateCaret(HWND hwnd,HBITMAP hBitMap,int nWidth,int nHeight); 显示插字符 BOOL ShowCaret(HWND hWnd); 获取插字符的位置 BOOL GetCarerPos(LPPOINT lpPoint); 设置插字符 BOOL SetCaretPos(int X,int Y); 2.鼠标消息(1)不同样式的光标hCursor=LoadCursor();SetCursor(hCursor);可以更改光标的样式
(2)常用的鼠标消息定义wincl.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS的窗口可以接收鼠标双击的消息,通过SetDoubleClickTime()可以重新设定表示双击的时间间隔;捕捉所有鼠标消息SetCapture()、释放消息ReleaseCapture();获取鼠标屏幕坐标的函数GetCursorPos(),将屏幕坐标转换成窗口坐标ScreenToClient()
(3)鼠标消息中的字参数和长字参数用LOWORD()获取长字参数的低位得到鼠标的窗口位置x坐标,用HIWORD()获取长字参数的高位得到鼠标啊的窗口位置y坐标;鼠标消息中的字参数是否有效可以通过和下面常量按位与&来判断
六、程序的资源1.菜单资源(1)定义菜单自定义的菜单项名称 MENU[,载入特性选项] BEGIN 菜单项列表 END 载入特性选项
由POPUP、MENUITEM定义的菜单项列表 POPUP定义弹出式菜单、弹出式菜单可以包含MENUITEM定义的菜单,如果菜单项名称中有&字母、那么它就获得了热键(alt+字母进行访问) POPUP “自定义的菜单项名称”[,选项] BEGIN 菜单项列表 END 选项
MENUITEM定义的菜单项 自定义的菜单项标识是提前自定义的常量用于区别其他菜单项,WM_COMMAND消息中字参数wParam的低字段包含这些定义过的常量;这些常量一般在.h文件中定义,在需要的地方使用#include引入 MENUITEM “自定义的菜单项名称”,自定义的菜单项标识[,选项] //创建菜单中的水平分隔符 MENUITEM SEPARATOR (2)加载菜单资源窗口类中加载 wincl.lpszMenuName = "OwnMenu"; 创建窗口时加载 CreateWindow(,LoadMenu(hThisInstance,"OwnMenu"),); 动态加载 BOOL SetMenu( HWND hwnd, HMENU hmenu); (3)操作菜单项获取主菜单句柄 hmenu=GetMenu(hwnd); 禁用或激活菜单项,可以在初始化的时候资源描述文件中设置禁用或激活,也可以调用函数 BOOL EnableMenuItem(HMENU hmenu,UINT enableItem,UINT dwEnable); EnableMenuItem(hmenu,OWN_CLOSE,MF_BYCOMMAND|MF_DISABLED); dwEnable是操作标识,通过或|可以选择多个操作标识
设置或取消选中标志,可以在资源描述文件中使用CHECKED,也可以调用函数 DWORD CheckMenuItem( HMENU hmenu, UINT itemID, //dwCheck的取值是MF_CHECKED或MF_UNCHECKED UINT dwCheck); 在菜单中插入菜单项 BOOL InsertMenu( HMENU hmenu, //菜单项的ID值或者菜单项的下标(下标从0开始) UINT position, //MF_BYCOMMAND|MF_ENABLED或MF_BYCOMMAND|MF_DISABLED或MF_POPUP|MF_BYPOSITION UINT flags; UINT itemID, LPCTSTR lpNewItem); 删除菜单项 BOOL DeleteMenu( HMENU hmenu, UINT position, //flags取MF_BYCOMMAND或者MF_POSITION UINT flags); 修改菜单项 BOOL ModifyMenu( HMENU hmenu, //取MF_COMMAND就可以 UINT flags, UINT newItemID, LPCTSTR lpNewItem); 动态地创建菜单 HMENU hmenu=CreateMenu(); HMENU hmenu1=CreateMenu(); InsertMenu(hmenu1,(UINT)hmenu1,MF_BYCOMMAND|MF_ENABLED,OWN_NEW,"新建"); InsertMenu(hmenu1,"修改"); HMENU hmenu2=CreateMenu(); InsertMenu(hmenu2,(UINT)hmenu2,"新建"); InsertMenu(hmenu2,"修改"); AppendMenu(hmenu,MF_POPUP,"菜单1"); AppendMenu(hmenu,"菜单2"); SetMenu(hwnd,hmenu); 重新显示窗口菜单 DrawMenuBar(hwnd); 2.加速键资源同样是在WM_COMMAND的字参数低字节获取对应的消息 (1)定义加速键资源加速键表名 ACCELERATORS BEGIN 加速键资源描述 END 加速键资源描述 //这是Ctrl组合的加速键,NOINVERT表示菜单项不高亮显示,ALT、SHIFT、CONTROL表示组合方式 “^字母”,id值,ASCII,[NOINVERT][ALT][SHIFT][CONTROL] //这是使用虚拟键的加速键,需要额外使用头文件windows.h 虚拟键,VIRTKEY,[NOINVERT][ALT][SHIFT][CONTROL] (2)载入加速键资源HACCEL hacc=LoadAccelerators( //当前应用的句柄 hInstance, //加速键表名 lpAcceIName;) (3)翻译加速键//一个应用程序只有一个消息循环,非模态对话框的捕获也是要放在这个地方 MSG message; While(GetMessage(&message,0) { If(!TranslateAccelerator(hwnd,hacc,&message)) { TranslateMessage(&message); DispatchMessage(&message); } } 3.位图资源(1)定义位图资源位图的ID值 BITMAP “位图的全称” (2)初始化定义一个位图句柄 HBITMAP hBitmap; 加载或创建位图资源 加载位图 hBitmap=LoadBitmap( //当前应用的句柄,可能需要全局变量来传入 hInstance, //定义过的位图的ID值 MAKEINTRESOURCE(bitmapID)); 创建位图 hBitmap=CreateCompatibleBitmap( hdc, //位图的宽度 nWidth, //位图的高度 nHeight); 选入内存设备环境,位图进入设备环境后就可以编辑位图 case WM_CREATE: hdc=GetDC(hwnd); hMemDC=CreateCompatibleDC(hdc); hBitmap=LoadBitmap(hins,MAKEINTRESOURCE(IDB_BITMAP1)); //选入内存设备环境 SelectObject(hMemDC,hBitmap); GetObject(hBitmap,sizeof(BITMAP),&bitmap); ReleaseDC(hwnd,hdc); break; (3)输出位图获取位图的尺寸 //这个宽度是bitmap.bmWidth,高度是bitmap.bmHeight GetObject(hBitmap,&bitmap); 获取窗口的尺寸 //这个宽度是clientRect.right-clientRect.left,高度是clientRect.bottom-clientRect.top GetClientRect(hwnd,&clientRect); 按原图像尺寸输出 BOOL BitBlt( //目标设备环境句柄 HDC hdc, //目标显示位置 int xDest,int yDest, //显示的宽度和高度 int nWidth,int nHeight, //之前定义的内存设备环境 HDC hMemDC, //源位图中要显示的位置 int xSrc,int ySrc, //操作选择 DWORD dwRop); 操作选择
可缩放的图像输出 BOOL StretchBlt( //目标设备环境句柄 HDC hdc, //显示的宽度和高度 int nWidthDest,int nHeightDest, //源位图要显示的位置 int xSrc, //源位图要显示的宽度和高度 int nWidthSrc,int nHeightSrc, //操作选择 DWORD dwRop); 4.对话框资源显式的向消息队列发消息SendMessage(hwnd,WM_DESTROY,0);;对话框中SetDlgItemText()可以设置控件的显示文字、GetDlgItemText()可以获得控件中的文字;GetParent()可以获得对话框的父窗口 (1)模式对话框不关闭这个对话框就无法和应用的其他窗口交互 ① 定义对话框资源 自定义对话框名称 DIALOGEX [载入特性选项],xDialogEx,yDialogEx,widthDialogEx,heightDialogEx //定义样式的时候需要用到头文件#include "afxres.h",WS_POPUP|WS_CAPTION|WS_VISIBLE一般会用到 STYLE 对话框常用样式|窗口常用样式 FONT 字体大小,”字体名称” CAPTION “标题名称” BEGIN 对话框的常用控件 “自定义的控件名称”,自定义的控件的ID值,x,y,width,height END 自定义对话框名称在头文件中定义、对于无意义但是非要定义ID的可以使用同一个ID值ID.._STATIC,载入特性选项和菜单资源的相同 对话框常用样式
对话框常用控件
② 调用对话框 INT_PRINT DialogBox( //当前应用程序的句柄,((LPCREATESTRUCT) lParam)->hInstance这种方法也可以得到 HINSTANCE hInstance, //使用MAKEINTRESOURCE加载对话框的ID值,或者使用LPCSTR强制转换这个ID LPCTSTR lpTemplate, //父窗口句柄 HWND hwndParent, //对话框的处理函数,可能需要强制转换 DLGPROC lpDialogFunc); ③ 对话框的处理函数 BOOL CALLBACK 对话框处理函数的名称(HWND hwnd,LPARAM lParam) { Switch(message) { case WM_INITDIALOG: … return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case 自定义的控件的ID值: … return TRUE; … } break; case WM_CLOSE: EndDialog(hwnd,0); Return TRUE; } //由系统完成 return FALSE; } ④ 关闭对话框 //nResult可以填触发控件的ID BOOL EndDialog(HWND hwnd,INT_PTR nResult); (2)Windows消息框MessageBox这是系统内置的模态对话框 int MessageBox( //Windows消息框的父窗口 HWND hwnd, //显示的内容 LPCTSTR lpszText, //标题 LPCTSTR lpszCaption, //Windows消息框的类型 DWORD dwType); Windows消息框的类型
MessageBox的返回值
(3)非模式对话框不关闭这个对话框也可以和应用的其他窗口交互,非模态对话框和模态对话框有很多相似的地方,但是也有不同之处: ① 调用非模式对话框 HWND CreateDialog( //当前应用程序的句柄 HINSTANCE hInstance, //使用MAKEINTRESOURCE加载定义过的非模式对话框的ID值 LPCTSTR lpTemplate, //非模式对话框的处理函数 DLGPROC lpDialogFunc); ② 截获非模式对话框消息的消息循环 MSG message; while(GetMessage(&message,0)) { //这个hdlg是个HWND类型的全局变量,由CreateDialog()的返回值进行初始化 if(!IsDialogMessage(hdlg,&message)) { TranslateMessage(&message); DispatchMessage(&message); } } ③ 关闭非模态对话框 BOOL DestroyWindow(HWND hdlg); 5.图标资源定义图标资源 定义的图标ID值 ICON “图标全称” 加载图标 wincl.hIcon = LoadIcon (hThisInstance,MAKEINTRESOURCE(IDI_552)); wincl.hIconSm = LoadIcon (hThisInstance,MAKEINTRESOURCE(IDI_552)); 七、Windows标准控件设置控件文件SetWindowText()、设置控件文件GetWindowText()是比较通用的函数;Windows标准控件是指无需定义,用CreateWindow(_T(“”),…)即可调用的控件,其中倒数第三个参数可以是自定义的(HMENU)ID,在WM_COMMAND的子参数低字节可以找到它的信息 1.静态控件(1)创建方法 CreateWindow(_T(“static”),…);得到静态的文字 2.按钮(1)创建方法CreateWindow(_T(“button”),…); (2)按钮的样式
3.列表框(1)创建方法CreateWindow(_T(“listbox”),…); (2)常用属性WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD 4.滚动条(1)创建方法CreateWindow(_T(“scrollbar”,…); 5.编辑框(1)创建方法CreateWindow(_T(“edit”,…); (2)常用属性WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |WS_BORDER | ES_LEFT | ES_MULTILINE |ES_AUTOHSCROLL | ES_AUTOVSCROLL 6.组合框(1)创建方法CreateWindow(_T(“combobox”,…); 八、单文档与多文档1.CC++多线程对于需要较长执行时间的功能模块,如果只放在主线程不分出线程的话,可能会造成UI无响应的糟糕情况 //用宏定义的变量加上条件语句的判断可以动态控制线程的开启和结束 _beginthread(timer,NULL); VOID timer(PVOID pvoid){…;_endthread();} 九、附录1.应用程序的发布当前工程->Properties->Built Targets->Type->GUI application; 选择Release编译 2.参考网址
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |