【Windows編程】系列第八篇:通用對話框

上一篇咱們學習了菜單的基本編程,本篇來了解一下通用對話框的使用。Windows系統之因此是目前最流行的桌面系統,也是由於Windows有一套標準化,統一友好的交互界面,好比菜單、工具欄、狀態欄以及各個控件。固然除了這些單獨的控件以外,對於像文件打開、保存對話框,字體對話,顏色對話框等對於Windows自己會用到,在不少第三方的應用程序中也會用到。所以微軟公司也早就清楚這種現實狀況會存在,因此Windows把這種常見的公共對話就作了統一的接口函數,供Windows本身和第三方開發者使用。java

Windows提供的公用對話框在不一樣的版本有所不同,但常見的公用對話框有:顏色選擇對話框、打開文件對話框、保存文件對話框、字體選擇對話框、查找對話框、替換對話框、打印對話框以及打印設置對話框等。程序員

本篇以最多見的文件打開/保存對話框、字體對話框、顏色對話框爲例,來學習如何建立這些對話框,其餘的對話框使用大同小異,且在MSDN上基本都有使用實例。編程

要使用公用對話框函數,須要包含commdlg.h頭文件,相關的數據結構和函數定義都在該頭文件中定義。windows

  • 文件打開對話框數組

文件打開對話框主要用於選擇須要的文件,把選擇的文件全路徑名傳給用戶,至於取到文件全路徑以後怎麼操做徹底是開發者本身決定。也就是說它提供了一個在電腦中選擇任何文件的公共操做接口。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/,謝謝合做!

相關文章
相關標籤/搜索