【Windows编程】系列第八篇:通用对话框

windows 专栏收录该内容
9 篇文章 0 订阅


上一篇我们学习了菜单的基本编程,本篇来了解一下通用对话框的使用。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:该参数用于设置打开或保存对话的文件格式过滤,比如下图中的文件过滤情景,相信所有的读者朋友都见过:

filter

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运行后的文件选择对话框如下:

fileopen

选择颜色对话框如下:

colordlg

选择字体对话框如下:

fontdlg

在demo中选择三个对话框后,选择的文件、颜色和字体均画在窗口上:

commdlg

以上只是演示了文件打开/保存、颜色选择和字体选择对话框,虽然只演示了最简单的功能,但也是最基本、最常用的功能,能满足不少应用需求,更多的函数及用法请参考MSDN,学会查MSDN是Windows平台上开发的必备基础。

  更多经验交流可以加入Windows编程讨论QQ群454398517


关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。

【Windows编程】系列第七篇:Menubar的创建和使用

转载请注明出处http://www.coderonline.net/,谢谢合作!


  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

摘要本书提供Windows 用户接口编程元素方面的参考资料。用户接口的编程类型主要有:按钮、编辑和静态控件、组合框和列表框、滚动条、插入符、光标、图标、菜单和字符串资源、键盘加速键、通用对话框库、对话框窗口操作、消息和消息队列、多文档界面、时钟、窗口类、过程、属性。对于这些用户接口编程元素,本书首先对它们进行简要概述,然后介绍与之相关的所有API函数、消息和结构,并给出精辟的解释。本书还提供了在编程过程中使用这些函数、消息和结构的注意事项和使用技巧。编辑推荐本书提供Windows 用户接口编程元素方面的参考资料。用户接口的编程类型主要有:按钮、编辑和静态控件、组合框和列表框、滚动条、插入符、光标、图标、菜单和字符串资源、键盘加速键、通用对话框库、对话框窗口操作、消息和消息队列、多文档界面、时钟、窗口类、过程、属性。对于这些用户接口编程元素,本书首先对它们进行简要概述,然后介绍与之相关的所有API函数、消息和结构,并给出精辟的解释。本书还提供了在编程过程中使用这些函数、消息和结构的注意事项和使用技巧。作者简介在Windows平台上开发应用程序对于每个开发人员来说都是一个巨大的挑战,因为不仅要了解该系统的方方面面,并且要能在浩如烟海的参考资料中找到所需的信息。“Win32开发人员参考库”套书的出版给广大Win32开发人员带来了福音。本套书针对Win32编程环境的特定领域分成5卷:第1卷“Windows 基本服务”、第2卷“Windows 用户接口”、第3卷“Windows 图形设备接口”、第4卷“Windows 通用控件”、第5卷“Windows Shell”。每卷都根据技术或者开发概念进行逻辑分组,从而使得开发人员能快速找到所需的编程信息。尤为重要的一点是:本书包括了Microsoft开发者网络库(MSDN)中有关编程参考中的主要内容,它包含关于Windows编程详尽的、权威的信息,因此只要手头有这么一本参考书就足以应付某一领域的编程问题了。 本书是“Win32开发人员参考库”的第2卷,是开发Windows应用程序的用户接口的必备参考资料。主要介绍各种控件、资源、用户输入和窗口操作的有关函数、消息和结构。这些信息对于开发人员来说极其重要。由于这些内容按用户接口类型进行分类,因此开发人员可以非常容易地查阅到所需的信息。 本书的译者具有多年使用Microsoft Visual C++开发Windows应用程序的经验,对Windows系统比较熟悉,从而使得本译文通俗易懂,符合中国人的思维习惯。 本书由前导工作室组织翻译,前导工作室的全体人员共同完成了本书的翻译、录排、统校等工作。主要参加人员包括:第1章到第7章由徐愿心负责翻译,第8章和第9章由徐之刚负责翻译。同时参加翻译工作的还有施惠琼、方杰、张廷辉、陈指挥、倪志红、赵朗、徐睿胤、钱建国、严俊、施晓东、盛仕辉、陈根样、何义等。全书最后由施平安进行校对,陈彦海负责进行统稿并进行质量把关。 在翻译过程中,我们对本书中出现的术语都进行了仔细的推敲和研究,但由于本书的内容涉及用户接口的方方面面,有些方面译者在自己的开发体验中较少涉足,且市面上与此相关的参考书籍较少,加上时间仓促,因此疏漏和争议之处在所难免,望广大读者提出宝贵的意见。
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值