【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程序演示以上几种公共对话框的基本用法。由于篇幅原因,进提供重要的创建片段,要查看完整代码,请点击下面 “阅读原文” 进行查看。
创建文件对话框:
OPENFILENAME ofn;
TCHAR ext[] = TEXT(".dat");
TCHAR szFile[MAX_PATH] = TEXT("default");
TCHAR szFilter[] = TEXT("文本文件 (*.txt) *.txt ")
TEXT("数据文件 (*.dat) *.dat ")
TEXT("All Files (*.*) *.* ");
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);
}
创建颜色对话框:
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);
}
创建字体对话框:
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);
}
以上demo运行后的文件选择对话框如下:
选择颜色对话框如下:
选择字体对话框如下:
在demo中选择三个对话框后,选择的文件、颜色和字体均画在窗口上:
以上只是演示了文件打开/保存、颜色选择和字体选择对话框,虽然只演示了最简单的功能,但也是最基本、最常用的功能,能满足不少应用需求,更多的函数及用法请参考MSDN,学会查MSDN是Windows平台上开发的必备基础。更过经验交流可以加windows专用讨论群,454398517
文本为原创文章,未经许可,谢绝转载!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- springboot消息之@RabbitListener和@EnableRabbit
- c++实例之通讯录管理系统之显示菜单和退出功能(一)
- c++实例之通讯录管理系统之添加联系人功能(二)
- c++实例之通讯录管理系统之显示联系人功能(三)
- c++实例之通讯录管理系统之删除联系人功能(四)
- springboot检索之Elasticsearch简介
- c++实例之通讯录管理系统之查找联系人功能(五)
- 【python-leetcode424-滑动窗口法】替换后的最长重复字符
- c++实例之通讯录管理系统之修改联系人功能(六)
- 解决arxiv.org打开pdf缓慢问题
- c++实例之通讯录管理系统之清空联系人功能(七)
- springboot任务之定时任务
- springboot检索之整合elasticsearch并使用jest操作
- springboot任务之邮件任务
- springboot安全之整合spring security实现(只有登录才有权限、不同用户显示不同内容、记住我)