【Windows编程】系列第八篇:通用对话框
上一篇我们学习了菜单的基本编程,本篇来了解一下通用对话框的使用。Windows系统之所以是目前最流行的桌面系统,也是因为Windows有一套标准化,统一友好的交互界面,比如菜单、工具栏、状态栏以及各个控件。当然除了这些单独的控件之外,对于像文件打开、保存对话框,字体对话,颜色对话框等对于Windows本身会用到,在很多第三方的应用程序中也会用到。因此微软公司也早就清楚这种现实情况会存在,所以Windows把这种常见的公共对话就做了统一的接口函数,供Windows自己和第三方开发者使用。
Windows提供的公用对话框在不同的版本有所不一样,但常见的公用对话框有:颜色选择对话框、打开文件对话框、保存文件对话框、字体选择对话框、查找对话框、替换对话框、打印对话框以及打印设置对话框等。
本篇以最常见的文件打开/保存对话框、字体对话框、颜色对话框为例,来学习如何创建这些对话框,其他的对话框使用大同小异,且在MSDN上基本都有使用实例。
要使用公用对话框函数,需要包含commdlg.h头文件,相关的数据结构和函数定义都在该头文件中定义。
- 文件打开对话框
文件打开对话框主要用于选择需要的文件,把选择的文件全路径名传给用户,至于取到文件全路径之后怎么操作完全是开发者自己决定。也就是说它提供了一个在电脑中选择任何文件的公共操作接口。API函数定义如下:
- BOOL GetOpenFileName(LPOPENFILENAME lpofn);
参数lpofn的定义如下:
- typedef struct tagOFN {
- DWORD lStructSize;
- HWND hwndOwner;
- HINSTANCE hInstance;
- LPCTSTR lpstrFilter;
- LPTSTR lpstrCustomFilter;
- DWORD nMaxCustFilter;
- DWORD nFilterIndex;
- LPTSTR lpstrFile;
- DWORD nMaxFile;
- LPTSTR lpstrFileTitle;
- DWORD nMaxFileTitle;
- LPCTSTR lpstrInitialDir;
- LPCTSTR lpstrTitle;
- DWORD Flags;
- WORD nFileOffset;
- WORD nFileExtension;
- LPCTSTR lpstrDefExt;
- LPARAM lCustData;
- LPOFNHOOKPROC lpfnHook;
- LPCTSTR lpTemplateName;
- #if (_WIN32_WINNT >= 0x0500)
- void * pvReserved;
- DWORD dwReserved;
- DWORD FlagsEx;
- #endif // (_WIN32_WINNT >= 0x0500)
- } OPENFILENAME, *LPOPENFILENAME;
该接口定义的各个参数成员请参考MSDN的详细解释,这里我们最常用到的几项如下:
lpstrFilter:该参数用于设置打开或保存对话的文件格式过滤,比如下图中的文件过滤情景,相信所有的读者朋友都见过:
lpstrFile:该参数用于保存选择结束后的选择文件。
nMaxFile:该参数指出上面用于保存结果文件的buffer字符长度。
Flags:该参数最常见用于设置是否可以多选,其他请查看MSDN。
- 文件保存对话框
文件保存对话框跟文件打开对话几乎完全一样,参数相同。功能也是为用户保存文件时选择或新建文件名、保存路径进行选择的公共操作接口。API函数定义如下:
- BOOL GetSaveFileName(LPOPENFILENAME lpofn);
该函数的参数与上面完全一样,只是有些不能在文件保存对话框函数中使用,保存文件时不能多选名字。
- 颜色选择对话框
该对话框函数提供统一接口用于选择颜色,API函数定义如下:
- BOOL ChooseColor(LPCHOOSECOLOR lpcc);
参数lpcc最重要的参数:
lpCustColors,它指向一个包含16个值的数组,该数组包含了对话框中自定义颜色的红、绿、蓝(RGB)值。如果用户修改这些颜色,系统将用新的颜色值更新这个数组。如果要在多个ChooseColor函数中保存这个新的数组,我们应该为该数组分配静态内存空间。
rgbResult:该参数保存了选择的颜色值。
- 字体选择对话框:
该对话框函数用于浏览并选择字体,包括颜色。API函数定义如下:
- BOOL ChooseFont(LPCHOOSEFONT lpcf);
对话框函数运行结束后的字体在rgbColors参数中,我们可以用它来创建选择的字体。
以上各个结构的其他成员请参考MSDN。
下面我们以一个demo程序演示以上几种公共对话框的基本用法。
- #include <windows.h>
- #include <tchar.h>
- #pragma comment(linker,"\"/manifestdependency:type='win32' "\
- "name='Microsoft.Windows.Common-Controls' "\
- "version='6.0.0.0' processorArchitecture='*' "\
- "publicKeyToken='6595b64144ccf1df' language='*'\"")
- #define IDC_FILE_DIALOG 1001
- #define IDC_COLOR_DIALOG 1002
- #define IDC_FONT_DIALOG 1003
- static TCHAR szAppName[] = TEXT("CommonDialog");
- static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
- {
- HWND hWnd;
- MSG msg;
- WNDCLASS wndclass;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass(&wndclass))
- {
- MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
- return 0;
- }
- hWnd = CreateWindow(szAppName, // window class name
- szAppName, // window caption
- WS_OVERLAPPEDWINDOW, // window style
- CW_USEDEFAULT, // initial x position
- CW_USEDEFAULT, // initial y position
- 400, // initial x size
- 300, // initial y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL); // creation parameters
- ShowWindow(hWnd, iCmdShow);
- UpdateWindow(hWnd);
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hDC;
- switch (message)
- {
- case WM_CREATE:
- CreateWindow(TEXT("BUTTON"), TEXT("file dialog"), WS_CHILD|WS_VISIBLE, 20, 40, 160, 40, hWnd, (HMENU)IDC_FILE_DIALOG, NULL, NULL);
- CreateWindow(TEXT("BUTTON"), TEXT("color dialog"),WS_CHILD|WS_VISIBLE, 20, 100, 160, 40, hWnd, (HMENU)IDC_COLOR_DIALOG, NULL, NULL);
- CreateWindow(TEXT("BUTTON"), TEXT("font dialog"), WS_CHILD|WS_VISIBLE, 20, 160, 160, 40, hWnd, (HMENU)IDC_FONT_DIALOG, NULL, NULL);
- return 0;
- case WM_COMMAND:
- {
- int wmId = LOWORD(wParam);
- switch (wmId)
- {
- case IDC_FILE_DIALOG:
- {
- OPENFILENAME ofn;
- TCHAR ext[] = TEXT(".dat");
- TCHAR szFile[MAX_PATH] = TEXT("default");
- TCHAR szFilter[] = TEXT("文本文件 (*.txt)\0*.txt\0")
- TEXT("数据文件 (*.dat)\0*.dat\0")
- TEXT("All Files (*.*)\0*.*\0\0");
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hWnd;
- ofn.lpstrFilter = szFilter;
- ofn.nFilterIndex = 1; // 1 to default show *.txt type file; 2 to default show *.dat type file.
- ofn.lpstrFile = szFile;
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrDefExt = ext;
- ofn.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT;
- if (GetOpenFileName(&ofn))//GetOpenFileName, GetSaveFileName
- {
- //将选择的文件输出到窗口
- LPTSTR file = ofn.lpstrFile; //file就是保存或者打开的文件名
- hDC = GetDC(hWnd);
- TextOut(hDC, 200, 50, ofn.lpstrFile, _tcslen(ofn.lpstrFile));
- ReleaseDC(hWnd, hDC);
- }
- }
- break;
- case IDC_COLOR_DIALOG:
- {
- CHOOSECOLOR cc;
- static COLORREF acrCustClr[16];
- ZeroMemory(&cc, sizeof(cc));
- cc.lStructSize = sizeof(cc);
- cc.hwndOwner = hWnd;
- cc.lpCustColors = (LPDWORD)acrCustClr;
- if (ChooseColor(&cc))
- {
- //用选择的颜色画一个实心矩形
- RECT rect = {240, 100, 340, 140};
- hDC = GetDC(hWnd);
- HBRUSH hBrush = CreateSolidBrush(cc.rgbResult);
- SelectObject(hDC, hBrush);
- FillRect(hDC, &rect, hBrush);
- DeleteObject(hBrush);
- ReleaseDC(hWnd, hDC);
- }
- }
- break;
- case IDC_FONT_DIALOG:
- {
- CHOOSEFONT cf;
- LOGFONT lf;
- ZeroMemory(&cf, sizeof(cf));
- cf.lStructSize = sizeof(cf);
- cf.hwndOwner = hWnd;
- cf.lpLogFont = &lf;
- cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
- if (ChooseFont(&cf))
- {
- //用选择的字体输出一行测试文本
- TCHAR str[] = TEXT("Font 测试!");
- HFONT hFont = CreateFontIndirect(cf.lpLogFont);
- DWORD rgbCurrent = cf.rgbColors;
- hDC = GetDC(hWnd);
- SelectObject(hDC, hFont);
- SetTextColor(hDC, cf.rgbColors);
- TextOut(hDC, 200, 170, str, _tcslen(str));
- DeleteObject(hFont);
- ReleaseDC(hWnd, hDC);
- }
- }
- break;
- default:
- break;
- }
- }
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0 ;
- }
- return DefWindowProc (hWnd, message, wParam, lParam);
- }
以上demo运行后的文件选择对话框如下:
选择颜色对话框如下:
选择字体对话框如下:
在demo中选择三个对话框后,选择的文件、颜色和字体均画在窗口上:
以上只是演示了文件打开/保存、颜色选择和字体选择对话框,虽然只演示了最简单的功能,但也是最基本、最常用的功能,能满足不少应用需求,更多的函数及用法请参考MSDN,学会查MSDN是Windows平台上开发的必备基础。
更多经验交流可以加入Windows编程讨论QQ群:454398517。
关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。
转载请注明出处http://www.coderonline.net/,谢谢合作!
【Windows编程】系列第八篇:通用对话框的更多相关文章
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 走进windows编程的世界-----入门篇
1 Windows编程基础 1.1Win32应用程序基本类型 1) 控制台程序 不须要完好的windows窗体,能够使用DOS窗体方式显示 2) Win32窗体程序 包括窗体的程序,能够通过窗 ...
- 《Windows核心编程系列》八谈谈用内核对象进行线程同步
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...
- 深入学习jQuery选择器系列第八篇——过滤选择器之伪子元素选择器
× 目录 [1]通用形式 [2]反向形式 [3]首尾元素 [4]唯一元素 前面的话 本文是子元素选择器的续篇,主要介绍关于nth-of-type()选择器的内容.该部分内容并非没有出现在<锋利的 ...
- Java系列--第八篇 基于Maven的SSME之定时邮件发送
关于ssme这个我的小示例项目,想做到麻雀虽小,五脏俱全,看到很多一些web都有定时发送邮件的功能,想我ssme也加入一下这种功能,经查询相关文档,发现spring本身自带了一个调度器quartz,下 ...
- Python高级网络编程系列之第二篇
在上一篇中,我们深入探讨了TCP/IP协议的11种状态,理解这些状态对我们编写服务器的时候有很大的帮助,但一般写服务器都是使用C/Java语言,因为这些语言对高并发的支持特别好.我们写的这些简单的服务 ...
- Python高级网络编程系列之第一篇
在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...
- [C# 网络编程系列]专题八:P2P编程
引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...
- javascript运动系列第八篇——碰壁运动
× 目录 [1]匀速碰壁 [2]自由落体 [3]投掷碰壁[4]拖拽碰壁 前面的话 碰撞运动可能是运动系列里面比较复杂的运动了.碰撞可以分为碰壁和互碰两种形式,而碰撞前后的运动形式也可以分为变速和匀速两 ...
随机推荐
- php xml 文件读取 XMLReader
php xml 文件读取 <?php /** $xmlString = '<xml> <persons count="10"> <person ...
- Null value was assigned to a property of primitive type setter of
在SSH项目的开发中遇到了下面的错误: 检查后发现数据库和映射文件中这个字段是允许为空的,为什么还要出错呢?原来是因为这个字段是int的,int是基本类型,即使设置成可以为空也不能取空值. 解决的办法 ...
- HTML5标签与HTML4标签的区别示例介绍_html5教程技巧
(1)概念的变化: HTML5专注内容与结构,而不专注的表现 <header> <hgroup>导航相关数据</hgroup> </header> &l ...
- [moka同学笔记]php 获取时间(今天,昨天,三天内,本周,上周,本月,三年内,半年内,一年内,三年内)
<?php /** * php 获取时间(今天,昨天,三天内,本周,上周,本月,三年内,半年内,一年内,三年内) * * author:ihelloworld2010@gmail.com * d ...
- php实现设计模式之 适配器模式
<?php /* * 适配器模式:将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作(结构型模式) * * 一个源接口,不符合 ...
- Idea开发环境中搭建Maven并且使用Maven打包部署程序
1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME的环境变量,然后将该变量添加到Path中 备注:必须要有JAVA_HOM ...
- 调用百度地图API
http://lbsyun.baidu.com/index.php?title=jspopular
- tomcat远程调试javaweb
当把一个本地项目部署到远程服务器后有可能出现意想不到错误,这个时候通过远程调试能够更清楚的找到bug所在位置. 目前百度tomcat绝大多数方法都是在startup.sh或者catalina.sh增加 ...
- 解决IE兼容模式问题
IE浏览器从IE8开始添加了兼容模式,开启后会以低版本的IE进行渲染.在浏览网页时候会出现网页显示问题,于是可以在html中加入以下代码来使IE使用固定的渲染模式: <metahttp-equi ...
- css相对定位和绝对定位
相对定位,是对原来元素的位置为参照物进行定位: 绝对定位,如果父级没有定位,则针对HTML为参照物进行定位:如果父级有定位,则针对父元素为参照物进行定位