Win32API学习笔记第七章(二)
来源:互联网 发布:红叶知弦调教 编辑:程序博客网 时间:2024/05/18 12:32
其实对话框不止这些(子窗口控件)
在书上我们可以看见,About3这个程序,实际上是自绘了一个确认图标。
首先我们自己给这个图标定义了一个类(说白了,这个图标实际上就是一个窗口,只是这里的窗口类被封装到了一个叫CustomControl的子窗口控制里面,这个控件会把Class这一栏空出来由用户自己选,然后实际上在创建了Dialog的时候就会调用CreateWindow来将这个用户自定的窗口创建出来。
再说下相互切换的Tab键相关的两个API:
GetNextDlgTabItem和GetNextGroupItem这里就可以得到前一个或后一个Tab键停留的组项(然后设置焦点就可以)同时,如果是自己的窗口的话,要加上WS_TABSTOP和WS_GROUP两个窗口风格才可以达到这个目的。
然后是非模态对话框:
1:
第一个是主窗口调用一个非模态对话框(这样子的对话框更像普通的子窗口一点)
此时我们需要自己为这个对话框写一个窗口过程,然后是创建窗口时:
CreateDialog(HINSTANCE,PTCHAR,父窗口窗口句柄 ,自己的窗口过程);
在窗口过程内我们就可以自定义各种各样的消息,并且可以在主窗口和这个对话框之间相互切换,而且很多的一些相关功能都有着对话框的性质,非常的方便
但是我们会发现一个问题:我们的消息循环只有一个,那要怎么办?
此时我们就要用到isDialogMessage这个函数来判断这个消息是否是属于后一个对话框的:
if(hWnd == 0||!isDialogMessage(hWnd,&msg)){ //默认的之前的窗口消息}
这个函数有两个作用,第一:如果这个消息时属于这个对话框的消息,那么它将返回一个非零值,并且将这个消息发送到相应的窗口过程去,其次:如果这个消息不属于这个对话框,那么就返回一个0。
之前加了一个判断hWnd是否为0是因为,如果为0他将继续用无效的窗口句柄进行调用这个函数,所以这里时加以验证的一个机制,并且,这个hWnd被置为全局,以便执行:
case WM_CLOSE: DestoryWindow(hWnd); hWnd = 0; return 0;
这里非模态和模态的区别之一就是这里并不是调用EndDialog。
2:
我们还可以直接就将这个对话框置为主窗口,这就会大大简化了代码:
WNDCLASS wcex; wcex.style = CS_HREDRAW | CS_VREDRAW | WS_VISIBLE; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = DLGWINDOWEXTRA; // 这里必须为DLGWINDOWEXTRA wcex.hInstance = hInstance;... wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass;//然后是注册,之后就用CreateDialog(HINSTANCE,PTCHAR,0,0);//后面两个为NULL就可以了
此时说实话这个就是一个窗口的创建(其尺寸,文字尺寸,标题都在资源文件里面声明了)两者时等价关系。
来看一个书上非常典型的例子:
/*---------------------------------------- HEXCALC.C -- Hexadecimal Calculator (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HexCalc") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = DLGWINDOWEXTRA ; // Note! wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (hInstance, szAppName) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ; ShowWindow (hwnd, iCmdShow) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ;}void ShowNumber (HWND hwnd, UINT iNumber){ TCHAR szBuffer[20] ; wsprintf (szBuffer, TEXT ("%X"), iNumber) ; SetDlgItemText (hwnd, VK_ESCAPE, szBuffer) ;}DWORD CalcIt (UINT iFirstNum, int iOperation, UINT iNum){ switch (iOperation) { case '=': return iNum ; case '+': return iFirstNum + iNum ; case '-': return iFirstNum - iNum ; case '*': return iFirstNum * iNum ; case '&': return iFirstNum & iNum ; case '|': return iFirstNum | iNum ; case '^': return iFirstNum ^ iNum ; case '<': return iFirstNum << iNum ; case '>': return iFirstNum >> iNum ; case '/': return iNum ? iFirstNum / iNum: MAXDWORD ; case '%': return iNum ? iFirstNum % iNum: MAXDWORD ; default : return 0 ; }}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static BOOL bNewNumber = TRUE ; static int iOperation = '=' ; static UINT iNumber, iFirstNum ; HWND hButton ; switch (message) { case WM_KEYDOWN: // left arrow --> backspace if (wParam != VK_LEFT) break ; wParam = VK_BACK ; // fall through case WM_CHAR: if ((wParam = (WPARAM) CharUpper ((TCHAR *) wParam)) == VK_RETURN) wParam = '=' ; if (hButton = GetDlgItem (hwnd, wParam)) { SendMessage (hButton, BM_SETSTATE, 1, 0) ; Sleep (100) ; SendMessage (hButton, BM_SETSTATE, 0, 0) ; } else { MessageBeep (0) ; break ; } // fall through case WM_COMMAND: SetFocus (hwnd) ; if (LOWORD (wParam) == VK_BACK) // backspace ShowNumber (hwnd, iNumber /= 16) ; else if (LOWORD (wParam) == VK_ESCAPE) // escape ShowNumber (hwnd, iNumber = 0) ; else if (isxdigit (LOWORD (wParam))) // hex digit { if (bNewNumber) { iFirstNum = iNumber ; iNumber = 0 ; } bNewNumber = FALSE ; if (iNumber <= MAXDWORD >> 4) ShowNumber (hwnd, iNumber = 16 * iNumber + wParam - (isdigit (wParam) ? '0': 'A' - 10)) ; else MessageBeep (0) ; } else // operation { if (!bNewNumber) ShowNumber (hwnd, iNumber = CalcIt (iFirstNum, iOperation, iNumber)) ; bNewNumber = TRUE ; iOperation = LOWORD (wParam) ; } return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
非常巧妙的是:
这里将所有的非Char类键盘消息全部丢给了默认的窗口过程处理,那么只需要在控件支持的情况下,我们就可以做到Tab切换等一系列操作,并且借助于每个消息之间的关系,将撤回键(VK_BACK)一直下调到COMMAND,回车键转化等等。。。。
(这个程序我自己在VS2017上实现,无法显示窗口,目前不知道原因,找到了原因的话会即使更新的)
- Win32API学习笔记第七章(二)
- Win32API学习笔记第七章(一)
- Win32API学习笔记第七章(三)
- Win32API学习笔记第五章(二)
- Win32API学习笔记第六章(二)
- Win32API学习笔记第五章(一)
- Win32API学习笔记第五章(三)
- Win32API学习笔记第六章(一)
- Win32API学习笔记第六章(三)
- Win32API学习笔记第六章(四)
- python学习笔记 第七章(二)
- Win32API学习笔记第二章
- Win32API学习笔记第三章
- Win32API学习笔记第四章
- Win32API学习笔记第八章
- Win32API学习笔记第一章
- Win32API多线程程序设计学习笔记
- 【《计算机网络(第七版)》学习笔记】二、 物理层
- Github使用教程------ Github客户端使用方法
- Left Right Action Support
- 使用线程池与内部类实现方法异步
- Spark Sql 编程式结构DataType转换 代码类小结
- 简单的纯java语言登录和注册功能
- Win32API学习笔记第七章(二)
- 第十一章(1至2节) 表示与描述
- LeetCode | 47. Permutations II
- 对Hadoop完全分布式集群下MapReduce日志的提取
- Tomcat运行Web项目,Action中实现资源同步
- JSP
- Redis(Windows)下的开启
- [转载]thinkphp3.2+bootstrap-inputfile多文件上传
- insert/insert all/insert first详解