zoukankan      html  css  js  c++  java
  • Windows编程系列:通用对话框

    打开文件对话框

    打开文件对话框,主要用到GetOpenFileName函数,参数为指向OPENFILENAME结构体的指针

    1 BOOL GetOpenFileName(
    2   LPOPENFILENAME Arg1
    3 );

    使用方法如下:

     1 #include <windows.h>
     2 #include<iostream>
     3 
     4 int main()
     5 {
     6     OPENFILENAME ofn{};
     7     TCHAR szFile[260]{};       //文件名缓冲区
     8 
     9     ofn.lStructSize = sizeof(ofn);
    10     ofn.hwndOwner = NULL; //设置对话框拥有者句柄
    11     ofn.lpstrFile = szFile; //设置文件名缓冲区
    12     ofn.lpstrFile[0] = ''; 
    13     ofn.nMaxFile = sizeof(szFile); //设置所选文件路径缓冲区最大长度
    14     ofn.lpstrFilter = L"全部文件*.*文本文件*.txt";  //指定文件类型
    15     ofn.nFilterIndex = 1;  //文件类型选中的索引 从1开始
    16     ofn.lpstrFileTitle = NULL;  //选中的文件名(不包含路径,包含扩展名)
    17     ofn.nMaxFileTitle = 0;  //选中的文件名缓冲区最大长度
    18     ofn.lpstrInitialDir = NULL;  //初始路径
    19     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //用于初始化对话框的标志位 
    20 
    21 
    22     if (GetOpenFileName(&ofn) == TRUE)
    23         std::wcout << ofn.lpstrFile << std::endl;
    24 }

     

    保存文件对话框

    保存文件对话框和打开文件对话框的使用差不多,只需要把GetOpenFileName换成GetSaveFileName即可。

     1 #include <windows.h>
     2 #include<iostream>
     3 
     4 int main()
     5 {
     6     OPENFILENAME ofn{};
     7     TCHAR szFile[260]{};       //文件名缓冲区
     8 
     9     ofn.lStructSize = sizeof(ofn);
    10     ofn.hwndOwner = NULL; //设置对话框拥有者句柄
    11     ofn.lpstrFile = szFile; //设置文件名缓冲区
    12     ofn.lpstrFile[0] = ''; 
    13     ofn.nMaxFile = sizeof(szFile); //设置所选文件路径缓冲区最大长度
    14     ofn.lpstrFilter = L"全部文件*.*文本文件*.txt";  //指定文件类型
    15     ofn.nFilterIndex = 1;  //文件类型选中的索引 从1开始
    16     ofn.lpstrFileTitle = NULL;  //选中的文件名(不包含路径,包含扩展名)
    17     ofn.nMaxFileTitle = 0;  //选中的文件名缓冲区最大长度
    18     ofn.lpstrInitialDir = NULL;  //初始路径
    19     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //用于初始化对话框的标志位 
    20 
    21 
    22     if (GetSaveFileName(&ofn) == TRUE)
    23         std::wcout << ofn.lpstrFile << std::endl;
    24 }

    字体选择对话框

    选择字体对话框主要用到ChooseFont函数,参数为指向CHOOSEFONTA结构体的指针。

    1 BOOL WINAPI ChooseFont(
    2   _Inout_ LPCHOOSEFONT lpcf
    3 );

    使用方法如下:

     1     CHOOSEFONT cf{};
     2     static LOGFONT lf{};        // 逻辑字体结构
     3     static DWORD rgbCurrent = 0;  // 当前字体颜色
     4     HFONT hfont;
     5 
     6     cf.lStructSize = sizeof(cf);
     7     cf.hwndOwner = NULL;
     8     cf.lpLogFont = &lf;  //指向一个逻辑 字体
     9     cf.rgbColors = rgbCurrent;
    10     cf.Flags = CF_SCREENFONTS | CF_EFFECTS; //设置字体对话框选项
    11 
    12     if (ChooseFont(&cf) == TRUE)
    13     {
    14         hfont = CreateFontIndirect(cf.lpLogFont);  //创建逻辑字体
    15         rgbCurrent = cf.rgbColors;  //保存字体颜色
    16     }

    颜色选择对话框

    颜色选择对话框主要用到ChooseColor函数,参数为指向CHOOSECOLOR 结构体的指针。

    1 BOOL WINAPI ChooseColor(
    2   _Inout_ LPCHOOSECOLOR lpcc
    3 );

    使用方法如下:

     1 #include <windows.h>
     2 #include<iostream>
     3 
     4 int main()
     5 {
     6     CHOOSECOLOR cc{};
     7     static COLORREF acrCustClr[16]; //颜色对话框下面的16个自定义颜色存储空间
     8     HBRUSH hbrush;                
     9     static COLORREF rgbCurrent = 0;
    10 
    11     cc.lStructSize = sizeof(cc);
    12     cc.hwndOwner = NULL;
    13     cc.lpCustColors = (LPDWORD)acrCustClr;  
    14     cc.rgbResult = rgbCurrent;
    15     cc.Flags = CC_FULLOPEN | CC_RGBINIT;
    16 
    17     if (ChooseColor(&cc) == TRUE)
    18     {
    19         hbrush = CreateSolidBrush(cc.rgbResult);
    20         rgbCurrent = cc.rgbResult;
    21     }
    22 }

    打印对话框

    打印对话框主要用到PrintDlg函数,参数为指向PRINTDLG结构体的指针。

    1 BOOL WINAPI PrintDlg(
    2   _Inout_ LPPRINTDLG lppd
    3 );

    使用方法如下:

     1 PRINTDLG pd{};
     2     
     3     pd.lStructSize = sizeof(pd);
     4     pd.hwndOwner = NULL;
     5     pd.hDevMode = NULL;
     6     pd.hDevNames = NULL;
     7     pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE || PD_RETURNDC;
     8     pd.nCopies = 1;        //设置打印份数
     9     pd.nFromPage = 0xFFFF; //设置打印起始页号
    10     pd.nToPage = 0xFFFF;   //设置打印结束页号
    11     pd.nMinPage = 1;
    12     pd.nMaxPage = 0xFFFF;
    13 
    14     if (PrintDlg(&pd) == TRUE)
    15     {
    16         //打印操作
    17 
    18         //释放dc
    19         DeleteDC(pd.hDC);
    20     }

    打印属性页对话框(打印对话框增强版)

    主要用到PrintDlgEx函数,参数为指向PRINTDLGEX结构体的指针。

    1 HRESULT WINAPI PrintDlgEx(
    2   _Inout_ LPPRINTDLGEX lppd
    3 );

    使用方法:

     1 #include <windows.h>
     2 #include<iostream>
     3 
     4 int main()
     5 {
     6     HRESULT hResult;
     7     PRINTDLGEX pdx = { 0 };
     8     LPPRINTPAGERANGE pPageRanges = NULL;
     9 
    10     //分配PRINTPAGERANGE结构体数组内存
    11     pPageRanges = (LPPRINTPAGERANGE)GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
    12 
    13     if (!pPageRanges)
    14         return 0;
    15 
    16     // 初始化PRINTDLGEX结构体
    17     pdx.lStructSize = sizeof(PRINTDLGEX);
    18     pdx.hwndOwner = GetConsoleWindow();  //拥有者窗体句柄 不能为NULL (这里使用控制台程序测试,所以传入控制台窗体句柄)
    19     pdx.hDevMode = NULL;   
    20     pdx.hDevNames = NULL;
    21     pdx.hDC = NULL;     //设备上下文句柄
    22     pdx.Flags = PD_RETURNDC | PD_COLLATE;
    23     pdx.Flags2 = 0;
    24     pdx.ExclusionFlags = 0;
    25     pdx.nPageRanges = 0;
    26     pdx.nMaxPageRanges = 10;
    27     pdx.lpPageRanges = pPageRanges;
    28     pdx.nMinPage = 1;
    29     pdx.nMaxPage = 1000;
    30     pdx.nCopies = 1;
    31     pdx.hInstance = 0;
    32     pdx.lpPrintTemplateName = NULL;
    33     pdx.lpCallback = NULL;
    34     pdx.nPropertyPages = 0;
    35     pdx.lphPropertyPages = NULL;
    36     pdx.nStartPage = START_PAGE_GENERAL; 
    37     pdx.dwResultAction = 0;
    38 
    39     hResult = PrintDlgEx(&pdx);
    40 
    41     if ((hResult == S_OK) && pdx.dwResultAction == PD_RESULT_PRINT)
    42     {
    43         //打印操作
    44     }
    45 
    46     //资源释放
    47     if (pdx.hDevMode != NULL)
    48         GlobalFree(pdx.hDevMode);
    49     if (pdx.hDevNames != NULL)
    50         GlobalFree(pdx.hDevNames);
    51     if (pdx.lpPageRanges != NULL)
    52         GlobalFree(pPageRanges);
    53 
    54     //删除dc
    55     if (pdx.hDC != NULL)
    56         DeleteDC(pdx.hDC);
    57 
    58     return 0;
    59 }

    页面设置对话框

    页面设置对话框主要用到PageSetupDlg函数,参数为指向PAGESETUPDLG结构体的指针。

    1 BOOL WINAPI PageSetupDlg(
    2   _Inout_ LPPAGESETUPDLG lppsd
    3 );

    这里在进行页面预览时,需要设置一个钩子函数,用于对页面进行绘制。如下:

     1 UINT_PTR CALLBACK PaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
     2 {
     3     LPRECT lprc;
     4     COLORREF crMargRect;
     5     HDC hdc, hdcOld;
     6 
     7     switch (uMsg)
     8     {        
     9     case WM_PSD_MARGINRECT:
    10         hdc = (HDC)wParam;
    11         lprc = (LPRECT)lParam;
    12 
    13         // 获取系统High light颜色
    14         crMargRect = GetSysColor(COLOR_HIGHLIGHT);
    15 
    16         //创建系统突出显示颜色的点划线笔,然后将其选择到示例页面的DC中。
    17         hdcOld = (HDC)SelectObject(hdc, CreatePen(PS_DASHDOT, 1, crMargRect));
    18 
    19         //绘制Rectangle
    20         Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom);
    21 
    22         //还原dc
    23         SelectObject(hdc, hdcOld);
    24         return TRUE;
    25 
    26     default:
    27         return FALSE;
    28     }
    29     return TRUE;
    30 }

    使用方法:

     1 PAGESETUPDLG psd{};   
     2 
     3     psd.lStructSize = sizeof(psd);
     4     psd.hwndOwner = GetConsoleWindow(); // 演示使用控制台窗体
     5     psd.hDevMode = NULL; 
     6     psd.hDevNames = NULL; 
     7     psd.Flags = PSD_INTHOUSANDTHSOFINCHES | PSD_MARGINS |
     8         PSD_ENABLEPAGEPAINTHOOK;
     9     psd.rtMargin.top = 1000;
    10     psd.rtMargin.left = 1250;
    11     psd.rtMargin.right = 1250;
    12     psd.rtMargin.bottom = 1000;
    13     psd.lpfnPagePaintHook = PaintHook;
    14 
    15     if (PageSetupDlg(&psd) == TRUE)
    16     {
    17         //获取纸张尺寸和边距值。
    18         
    19     }

     有趣的是,按照MSDN文档上的说明,上述部分函数已经不推荐使用了。但在最新的.NET 5中,依旧使用了这些函数。

    推荐阅读:

    GetOpenFileName API

    https://docs.microsoft.com/en-us/windows/win32/api/commdlg/nf-commdlg-getopenfilenamea

    ChooseFont API

    https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms646914(v=vs.85)

    ChooseColor API

    https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms646912(v=vs.85)

    PrintDlgEx API

    https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms646942(v=vs.85)

  • 相关阅读:
    Undefined symbols for architecture armv7错误解决方法
    一个iOS 框架介绍:MKNetworkKit
    objective-c之各种数值
    利用openURL,在IOS应用中打开另外一个应用
    hackerrank---List Comprehensions
    LeetCode --- Plus One
    Vim学习与总结
    LeetCode --- Pascal's Triangle II
    LeetCode --- Gray Code
    LeetCode --- Two Sum
  • 原文地址:https://www.cnblogs.com/zhaotianff/p/13999133.html
Copyright © 2011-2022 走看看