【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)\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);
 }
 
 创建颜色对话框:
 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

文本为原创文章,未经许可,谢绝转载!

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-08-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏君赏技术博客

一键替换Key Mac软件的制作教程第一篇

我们要选择macOS的平台选择Cocoa Application的工程模板,点击Next.

611
来自专栏CDA数据分析师

Excel:Ctrl+F人人都会用,但这3个技巧99%的人不知道

本文为简书作者傲看今朝原创,CDA数据分析师已获授权。 查找与替换是Excel中最为简单实用的功能之一,几乎用过Excel的人都知道这个功能,也都会简单使用这个...

1945
来自专栏DeveWork

【译】WordPress 中的50个过滤器(2):先介绍10个过滤器

在上一篇文章中,我们介绍了WordPress 世界的过滤器;本篇文章的话我们将要探索50个笔者精选的过滤器,并一一通过例子解释其如何工作的。 事不宜迟,让...

2066
来自专栏向治洪

Elcipse安装gradle插件

参考: http://www.gradle.org/docs/current/userguide/installation.html (1)下载Gradle ...

1638
来自专栏python学习之旅

Python django框架笔记(三):django工作方式简单说明和创建用户界面

1657
来自专栏代码GG之家

深入Android源码系列(一)

? 本文讲解内容有 loadLibrary流程 linker ELF ndk开发以及配置调试版本 ndk-...

2126
来自专栏从零开始学 Web 前端

Sublime Text3 一些实用设置

当你把脑袋扭过到显示器以外的地方后再回头看编辑器,光标呢?然后你可能会花点小功夫找到他,就像你平时找鼠标的时候。这个设置会让让光标所处在的那一行高亮,只是稍微亮...

542
来自专栏小狼的世界

Vimperator:玩酷你的Firefox

First there was a Navigator, then there was an Explorer. Later it was time for a...

914
来自专栏更流畅、简洁的软件开发方式

你的SQL语句放在了哪里?

这段时间整理自然框架,遇到了一个老问题——SQL语句放在哪里? 对于有规律的比较好办了,但是对于哪些没啥规律的怎么办呢? 想了一下,有几种方式,弄了张图。欢迎大...

1678
来自专栏飞雪无情的博客

Go语言实战笔记(二十一)| Go 单元测试

相信我们做程序员的,对单元测试都不陌生。单元测试一般是用来测试我们的代码逻辑有没有问题,有没有按照我们期望的运行,以保证代码质量。

542

扫描关注云+社区