zoukankan      html  css  js  c++  java
  • 【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:该参数用于设置打开或保存对话的文件格式过滤,比如下图中的文件过滤情景,相信所有的读者朋友都见过:

    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)*.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);
    					}
    				}
    				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/,谢谢合作!

  • 相关阅读:
    K8S calico
    K9S之glusterfs
    kubeadm安装报错
    创建crd和cr
    分布式学习汇总
    容器常见问题分析
    项目迁移到k8s平台流程
    K8S storageclass
    awk命令
    K8S headless service服务详解
  • 原文地址:https://www.cnblogs.com/yangdanny/p/4709381.html
Copyright © 2011-2022 走看看