zoukankan      html  css  js  c++  java
  • 第11章 对话框_11.3 通用对话框

    11.3 通用对话框

    11.3.1 完善POPAD

    (1)通用对话框:#include<commdlg.h>

    (2)OPENFILENAME结构

    字段

    含义

    备注

    lStructSize

    结构体的大小

    hwndOwner

    所属窗口,可以为NULL

    hInstance

    lpstrFilter

    文件筛选字符串

     

    TCHAR szFilter[] =

      TEXT ("Text Files (*.TXT)*.txt")

    TEXT ("ASCII Files (*.ASC)*.asc")

      TEXT ("All Files (*.*)*.*");

    ①可由多组内容组成,每组包含一个说明字符串(红色)和一个筛选字符串(蓝色),字符串的最后用两个结束。

    ②筛选字符串可以同时指出多个扩展名,中间用分号隔开,如:*.txt;*.doc

    lpstrCustomFilter

    缓冲区,保留用户选择的过滤样式

    可以为NULL

    nMaxCustFilter

    lpstrCustomFilter准备的以TCHAR为单位的缓冲大小

    nFilterIndex

    当前选择的过滤器的索引

    0:指出是通过lpstrCustomFilter指定的定制过滤器

    1:lpstrFilter缓冲区的第1个索引。2为第2个索引,以此类推

    lpstrFile

    全路径文件名缓冲区

    (包含驱动器、路径、文件名和扩展名)

    ①对话框初始化时显示该文件名

    ②用户选择时,在些返回新的文件名

    nMaxFile

    lpstrFile缓冲区的大小

    lpstrFileTitle

    接收不含路径的文件名的缓冲区

    可以为NULL

    nMaxFileTitle

    lpstrFileTitle缓冲区大小,以TCHAR为单位

    lpstrInitialDir

    在这个字符串中指定初始目录

    可为NULL

    lpstrTitle

    对话框标题,默认为“打开”或“保存”

    Flags

    对话框不同行为的标志

    ①OFN_ALLOWMULTISELECT——允许多选

    ②OFN_CREATEPROMPT——用户输入不存在的文件名时,会提示“是否建立文件”

    ③OFN_FILEMUSTESTIST——只能选择一个己经存在的文件

    ④OFN_HIDEREADONLY——不显示“以只读方式打开”选择框

    ⑤OFN_OVERWRITEPROMPT——保存时,提问“是否覆盖文件”

    ⑥OFN_PATHMUSTEXIST——输入路径必须存在

    ⑦OFN_READONLY——“以只读方式打开”复选择处于选中状态

    nFileOffset

    返回文件名字符串中,文件名的起始位置

    如,当用户选择文件:“c;dir1file.txt”,时返回8,因为文件名file.txt的起始位置从8开始。

    nFileExtension

    扩展名在字符串中的起始位置

    lpstrDefExt

    指定默认的扩展名

    lCustData

    lpfnHook

    指向一个钩子程序

    Flags成员中包含OFN_ENABLEHOOK标记

    lpTemplateName

    是对话框模板资源

    Flags成员中设置OFN_ENABLETEMPLATE

    (3)“打开”或“保存”对话框函数:GetOpenFileName/GetSaveFileName

    11.3.2 Unicode文件

    (1)Unicode文件的判断——IsTextUnicode(lpBuffer,cb, lpi)

    ①lpBuffer参数:要测试的字符串,其缓冲区地址

    ②cb个参数:lpBuffer指向的字节数(注意是不是字符数)

    ③lpi:是个in/out类型的,传入时指定哪些测试项目,传出时为符合哪个测试项目。

    ④返回值:TRUE或FALSE

    (2)字符串的转化——这里的多字节是广义的,即可指ANSI,也可指UTF_8等。

     ①WideCharToMultiByte——将Unicode字符串转为多字节字符串

    字段

    功能

    CodePage

    CodePage参数用于标识要为转换新的字符串的相关代码页,如CP_ACP实现了Unicode与ANSI的转换;CP_UTF8 实现了Unicode与UTF-8的转换

    dwFlags

    进行额外的控制,会影响使用了读音符号(比如重音)的字符

    lpWideCharStr

    转换为宽字节字符串的缓冲区

    cchWideChar

    lpWideCharStr指向的缓冲区的字符个数。如果-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度(含)。

    lpMultiByteStr

    接收被转换字符串的缓冲区

    cchMultiByte

    lpMultiByteStr指向的缓冲区最大值(用字节来计量)

    lpDefaultChar

    遇到一个不能转换的宽字符,函数便会使用该参数指向的字符。

    pfUsedDefaultChar

    只要遇到任何一个不能被转换的字符,就会被函数设为TRUE。

    ②MultiByteToWideChar——将多字节字符串转为Unicode字符串

    字段

    功能

    CodePage

    用来标记与一个多字节字符串相关的代码页

    dwFlags

    进行额外的控制,会影响使用了读音符号(比如重音)的字符

    lpWideCharStr

    转换为宽字节字符串的缓冲区

    cchWideChar

    lpWideCharStr指向的缓冲区的字符个数,如果-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度(含)。

    lpMultiByteStr

    接收被转换字符串的缓冲区

    cchMultiByte

    lpMultiByteStr指向的缓冲区最大值(用字节来计量)

    lpDefaultChar

    遇到一个不能转换的宽字符,函数便会使用该参数指向的字符。

    pfUsedDefaultChar

    只要遇到任何一个不能被转换的字符,就会被函数设为TRUE。

    11.3.3 改变字体

    (1)CHOOSEFONT结构体

    字段

    说明

    lStructSize

    结构长度

    hwndOwner

    所属窗口

    hDC

    当Flags标志指定CF_PRINTERFONTS标志时,它是打印机的DC句柄

    lpLogFont

    指向一个LOGFONT结构

    iPointSize

    选择的字体的大小,单位是1/10磅

    rgbColors

    返回选择的字体的颜色。如果Flags字段的CF_EFFECTS被设置,将同时用该颜色初始化“颜色”下拉列表框

    nFontType

    从ChooseFont函数中返回用户选择的字体:BOLD_FONTTYPE、ITALIC_FONTTYPE、REGULAR_FONTTYPE、ITALIC_FONTTYPE、PRINTER_FONTTYPE、SCREEN_FONTTYPE等。

    Flags

    对话框显示设置:

    CF_BOTH:同时列出打印机字体和屏幕字体

    CF_TTONLY:只列出TrueType字体

    CF_EFFECTS:显示“效果”复选择

    CF_FIXEDPITCHONLY:只显示等宽字体

    CF_LIMITSIZE:显示字体的尺寸介于nSizeMin到nSizeMax之间

    CF_NOSTYLESEL:不显示“字形”组合列表框

    CF_NOSIZESEL:不显示“大小”组合列表框

    CF_SCREENFONTS:只显示屏幕字体

    (2)设置编辑框字体:SendMessage(hwndEdit,WM_SETFONT, (WPARAM)hFont, 0)

    11.3.4 查找和替换

    (1)FINDREPLACE结构的主要字段

    字段

    说明

    lStructSize

    结构体大小

    hwndOwner

    所属窗口,不能为NULL,必须设置。因为对话框是非模态的,要向父窗口发送查找或替换的消息。

    lpstrFindWhat

    查找字符串

    lpstrReplaceWith

    替换字符串,可为NULL,但在ReplaceText函数中须设置。

    wFindWhatLen

    查找字符串的长度(至少要80字节)

    wReplaceWithLen

    替换字符串的长度

    Flags

    ①FR_FINDNEXT、FR_REPLACE、FR_REPLACEALL、FR_DIALOGTERM——表示用户单击了“查找下一个”、“替换”、“全部替换”和“取消”

    ②FR_HIDEUPDOWN、FR_HIDEMATCHCASE、FR_HIDEWHOLEWORD:初始化时,表示对话框不显示“方向”、“区分大小写”、“全字匹配”按钮

    ③FR_NOMATCHCASE、FR_NOUPDOWN、FR_NOWHOLEWORD:将“区分大小写”、“方向”、“全字匹配”按钮灰化。

    ④FR_DOWN:把“方向”按钮设置为“向下”。

    (2)对话框是非模态的,所以消息循环应该调用IsDialogMessage。

    (3)FINDREPLACE结构不能声明为窗口过程的局部变量,必须是静态变量或全局变量。因为当调用FindText或ReplaceText调出对话框后,PopFindFindDlg(PopFindReplaceDlg)这些函数会立即返回。但该结构会作为消息的lParam参数被发送到父窗口的消息过程。为防止该结构被释放,要声明为静态变量。

    (4)“查找”或“替换”对话框与父窗口会进行一种特殊的消息进行通信。

    所以程序首先须通过FINDMSGSTR这个名字,向系统申请获得该特殊消息的ID号,即msgID =RegisterWindowMessage (FINDMSGSTRING)后就可以利用msgID进行通信了。

     【POPAD3程序】

     效果图:

    //CommFunc.h

    #include<windows.h>
    //Function in POPFILE.C
    void PopFileInitialize(HWND);
    BOOL PopFileOpenDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileSaveDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileRead(HWND, PTSTR);
    BOOL PopFileWrite(HWND, PTSTR);
    //Function in POPFIND.C
    HWND PopFindFindDlg(HWND);
    HWND PopFindReplaceDlg(HWND);
    BOOL PopFindFindText(HWND, int*, LPFINDREPLACE);
    BOOL PopFindNextText(HWND, int*);
    BOOL PopFindReplaceText(HWND, int*, LPFINDREPLACE);
    BOOL PopFindValidFind(void);
    //Functions in POPFONT.C
    void PopFontInitialize(HWND);
    BOOL PopFontChooseFont(HWND);
    void PopFontSetFont(HWND);
    void PopFontDeinitialize(void);
    //Functions in POPPRINT.C
    BOOL PopPrntPrintFile(HINSTANCE, HWND, HWND, PTSTR);

    //PopPad3.c

    /*------------------------------------------------------------
    POPPAD3.C -- Popup Editor Version3 (includes menu)
    (c) Charles Petzold, 1998
    ------------------------------------------------------------*/
    #include <windows.h>
    #include "resource.h"
    #include "CommFunc.h"
    #define ID_EDIT 1
    #define UNTITLED TEXT("(untitled)")
    static TCHAR szAppName[] = TEXT("PopPad3");
    static HWND hDlgModeless;
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        HACCEL hAccel;
        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, szAppName);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = szAppName;
        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
                            TEXT("edit3"), // window caption
                            WS_OVERLAPPEDWINDOW,        // window style
                            CW_USEDEFAULT,              // initial x position
                            CW_USEDEFAULT,              // initial y position
                            CW_USEDEFAULT,              // initial x size
                            CW_USEDEFAULT,              // initial y size
                            NULL,                       // parent window handle
                            NULL,                       // window menu handle
                            hInstance,                  // program instance handle
                            NULL);                     // creation parameters
    
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        hAccel = LoadAccelerators(hInstance, szAppName);
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (hDlgModeless == NULL || !IsDialogMessage(hDlgModeless, &msg))
            {
                //处理键盘加速键
                if (!TranslateAccelerator(hwnd, hAccel, &msg))
                {
                    //非键盘加速键消息的处理
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
        }
        return msg.wParam;
    }
    void OkMessage(HWND hwnd, TCHAR* szMessage, TCHAR* szTitleName)
    {
        TCHAR szBuffer[64 + MAX_PATH];
        wsprintf(szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED);
        MessageBox(hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION);
    }
    int AskConfirmation(HWND hwnd)
    {
        return MessageBox(hwnd, TEXT("Really Want to close PopPad3?"),
                          szAppName, MB_YESNO | MB_ICONQUESTION);
    }
    short AskAboutSave(HWND hwnd, TCHAR* szTitleName)
    {
        TCHAR szBuffer[64 + MAX_PATH];
        int iRet;
        wsprintf(szBuffer, TEXT("Save current changes in %s?"), szTitleName[0] ? szTitleName : UNTITLED);
        iRet = MessageBox(hwnd, szBuffer, szAppName, MB_YESNOCANCEL | MB_ICONQUESTION);
        if (iRet == IDYES)
        {
            if (!SendMessage(hwnd, WM_COMMAND, IDM_FILE_SAVE, 0))  //IDM_FILE_SAVE返回0为失败,1成功
                iRet = IDCANCEL;
        }
        return  iRet;
    }
    //设置标题
    void DoCaption(HWND hwnd, TCHAR* szTitleName)
    {
        TCHAR szCaption[64 + MAX_PATH];
        wsprintf(szCaption, TEXT("%s - %s"), szAppName,
                 szTitleName[0] ? szTitleName : UNTITLED);
        SetWindowText(hwnd, szCaption);
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static HWND hwndEdit;
        int iSelect, iEnable;
        static int iOffset;
        static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
        static bNeedSave = FALSE;
        static UINT messageFindReplace;
        LPFINDREPLACE pfr;
        switch (message)
        {
        case WM_CREATE:
            hwndEdit = CreateWindow(TEXT("edit"), NULL,
                                    WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                                    WS_BORDER | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL |  //ES_NOHIDESEL,编辑框在没有输入焦点时被选择的文字仍然被加亮
                                    ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                                    0, 0, 0, 0, hwnd, (HMENU)ID_EDIT,
                                    ((LPCREATESTRUCT)lParam)->hInstance, NULL);
            //限制编辑框的文本最大长度
            SendMessage(hwndEdit, EM_LIMITTEXT, 32000, 0L);
            PopFileInitialize(hwnd);
            PopFontInitialize(hwndEdit);
            messageFindReplace = RegisterWindowMessage(FINDMSGSTRING); //申请获取“查找”、“替换”发出的特殊消息的ID
            DoCaption(hwnd, szTitleName);
            return 0;
        case WM_SETFOCUS:
            SetFocus(hwndEdit);
            return 0;
        case WM_INITMENUPOPUP: //lParam:item position and indicator
            switch (lParam)
            {
            case 1:
                //Undo菜单项
                EnableMenuItem((HMENU)wParam, IDM_EDIT_UNDO,
                               SendMessage(hwndEdit, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED);
                //Paste菜单项
                EnableMenuItem((HMENU)wParam, IDM_EDIT_PASTE,
                               IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED);
                iSelect = SendMessage(hwndEdit, EM_GETSEL, 0, 0);
                if (HIWORD(iSelect) == LOWORD(iSelect))
                    iEnable = MF_GRAYED;
                else
                    iEnable = MF_ENABLED;
                EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, iEnable);
                EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, iEnable);
                EnableMenuItem((HMENU)wParam, IDM_EDIT_CLEAR, iEnable);
                break;
            case 2:  //“查找”菜单项
                //如果非模态对话框==NULL时,激活菜单
                iEnable = hDlgModeless == NULL ? MF_ENABLED : MF_GRAYED;
                EnableMenuItem((HMENU)wParam, IDM_SEARCH_FIND, iEnable);
                EnableMenuItem((HMENU)wParam, IDM_SEARCH_NEXT, iEnable);
                EnableMenuItem((HMENU)wParam, IDM_SEARCH_REPLACE, iEnable);
                break;
            }
            return 0;
        case WM_COMMAND:
            if (lParam && LOWORD(wParam == ID_EDIT))  //控件消息
            {
                switch (HIWORD(wParam)) //控件通知码
                {
                case EN_UPDATE:
                    bNeedSave = TRUE;
                    return 0;
                case EN_ERRSPACE:
                case EN_MAXTEXT:
                    MessageBox(hwnd, TEXT("Edit Control out of space."),
                               szAppName, MB_OK | MB_ICONSTOP);
                    return 0;
                }
                break;
            };
            switch (LOWORD(wParam))//加速键ID或菜单ID,这里两个ID相等
            {
                //菜单消息
            case IDM_FILE_NEW:
                //保存旧文件,如果保存时失败,则什么都不做,直接返回。
                if (bNeedSave&& IDCANCEL == AskAboutSave(hwnd, szTitleName))
                    return 0;
                SetWindowText(hwndEdit, TEXT("")); //清除编辑框内容
                szFileName[0] = '';
                szTitleName[0] = '';
                DoCaption(hwnd, szTitleName);
                bNeedSave = FALSE;
                return 0;
            case IDM_FILE_OPEN:
                //保存旧文件,如果保存时失败,则什么都不做,直接返回。
                if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, szTitleName))
                    return 0;
                if (PopFileOpenDlg(hwnd, szFileName, szTitleName))
                {
                    if (!PopFileRead(hwndEdit, szFileName))
                    {
                        OkMessage(hwnd, TEXT("Could not read file %s!"), szTitleName);
                        szFileName[0] = '';
                        szTitleName[0] = '';
                    }
                }
                DoCaption(hwnd, szTitleName);
                bNeedSave = FALSE;
                return 0;
            case IDM_FILE_SAVE:
                if (szFileName[0])
                {
                    if (PopFileWrite(hwndEdit, szFileName))
                    {
                        bNeedSave = FALSE;
                        return 1;
                    } else
                    {
                        OkMessage(hwnd, TEXT("Could not write file %s"), szTitleName);
                        return 0;
                    }
                }
                //如果是UNTITLE,则弹出保存对话框
            case IDM_FILE_SAVE_AS:
                if (PopFileSaveDlg(hwnd, szFileName, szTitleName))
                {
                    DoCaption(hwnd, szTitleName);
                    if (PopFileWrite(hwndEdit, szTitleName))
                    {
                        bNeedSave = FALSE;
                        return 1;
                    } else
                    {
                        OkMessage(hwnd, TEXT("Could not write file %s"), szTitleName);
                        return 0;
                    }
                }
                return 0;
            case IDM_FILE_PRINT:
                MessageBeep(0);
                return 0;
            case IDM_FORMAT_FONT:
                if (PopFontChooseFont(hwnd))
                {
                    PopFontSetFont(hwndEdit);
                }
                return 0;
            case IDM_SEARCH_FIND:
                //查找将从iOffset位置开始(首获取选中文本后面的位置iOffset)
                SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
                hDlgModeless = PopFindFindDlg(hwnd);
                return 0;
            case IDM_SEARCH_NEXT:
                //查找将从iOffset位置开始(首获取选中文本后面的位置iOffset)
                SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
                if (PopFindValidFind())
                    PopFindNextText(hwndEdit, &iOffset);
                else
                    hDlgModeless = PopFindFindDlg(hwnd);
                return 0;
            case IDM_SEARCH_REPLACE:
                //将查找将从iOffset位置开始(首获取选中文本后面的位置iOffset)
                SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
                hDlgModeless = PopFindReplaceDlg(hwnd);
                return 0;
            case IDM_APP_EXIT:
                SendMessage(hwnd, WM_CLOSE, 0, 0);
                return 0;
            case IDM_EDIT_UNDO:
                SendMessage(hwndEdit, WM_UNDO, 0, 0);
                return 0;
            case IDM_EDIT_CUT:
                SendMessage(hwndEdit, WM_CUT, 0, 0);
                return 0;
            case IDM_EDIT_COPY:
                SendMessage(hwndEdit, WM_COPY, 0, 0);
                return 0;
            case IDM_EDIT_PASTE:
                SendMessage(hwndEdit, WM_PASTE, 0, 0);
                return 0;
            case IDM_EDIT_CLEAR:
                SendMessage(hwndEdit, WM_CLEAR, 0, 0);
                return 0;
            case IDM_EDIT_SELECT_ALL:
                SendMessage(hwndEdit, EM_SETSEL, 0, -1);
                return 0;
            case IDM_HELP_HELP:
                MessageBox(hwnd, TEXT("Help not yet implement!"),
                           szAppName, MB_OK | MB_ICONEXCLAMATION);
                return 0;
            case IDM_APP_ABOUT:
                MessageBox(hwnd, TEXT("POPPAD3(c) Charles Petzold 1998!"),
                           szAppName, MB_OK | MB_ICONINFORMATION);
                return 0;
            }
            break;
        case WM_SIZE:
            MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            return 0;
        case WM_CLOSE: //选择窗口关闭按钮时收到该消息
            if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
                DestroyWindow(hwnd);
            return 0;
        case WM_QUERYENDSESSION: //系统关机或注销时收到该消息
            if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
                return 1;
            return 0;
        case WM_DESTROY:
            PopFontDeinitialize();
            PostQuitMessage(0);
            return 0;
        default:
            //处理“查找”、“替换”发送的特殊消息
            if (message == messageFindReplace)
            {
                pfr = (LPFINDREPLACE)lParam;
                //用户点击了“取消”按钮
                if (pfr->Flags & FR_DIALOGTERM)
                    hDlgModeless = NULL;
                //用户点击了“查找下一个”按钮
                if (pfr->Flags& FR_FINDNEXT)
                {
                    if (!PopFindFindText(hwndEdit, &iOffset, pfr))
                        OkMessage(hwnd, TEXT("Text not Find!"), TEXT(""));
                }
    
                //用户点击了“替换全部”
                if (pfr->Flags & FR_REPLACEALL)
                    while (PopFindReplaceText(hwndEdit, &iOffset, pfr));
                return 0;
            }
            break;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    //PopFile.c

    #include "CommFunc.h"
    static OPENFILENAME ofn;
    void PopFileInitialize(HWND hwnd)
    {
        static TCHAR szFilter[] = TEXT("Text Files(*.TXT)*.txt")
            TEXT("AscII Files(*.ASC)*.asc")
            TEXT("ALL Files(*.*)*.*");
        ofn.lStructSize = sizeof(OPENFILENAME);
        ofn.hwndOwner = hwnd;
        ofn.hInstance = NULL;
        ofn.lpstrFilter = szFilter;
        ofn.lpstrCustomFilter = NULL;
        ofn.nMaxCustFilter = 0;
        ofn.nFilterIndex = 0;
        ofn.lpstrFile = NULL;     //全路径文件名缓冲区,在“打开”和“保存”函数中设置
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFileTitle = NULL;   //文件名(含扩展名),在“打开”和“保存”函数中设置
        ofn.nMaxFileTitle = MAX_PATH;
        ofn.lpstrInitialDir = NULL;   //初始目录
        ofn.lpstrTitle = NULL;   //对话框标题
        ofn.Flags = 0;
        ofn.nFileOffset = 0;//全路径文件名字符串中,文件名的起始位置
        ofn.nFileExtension = 0;//全路径文件名字符串中,扩展名的起始位置
        ofn.lpstrDefExt = TEXT("txt");
        ofn.lCustData = 0L;
        ofn.lpfnHook = NULL;
        ofn.lpTemplateName = NULL;
    }
    BOOL PopFileOpenDlg(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
    {
        ofn.hwndOwner = hwnd;
        ofn.lpstrFile = pstrFileName;  //全路径文件名
        ofn.lpstrFileTitle = pstrTitleName;//文件名(含扩展名)
        ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT;
        return GetOpenFileName(&ofn);
    }
    BOOL PopFileSaveDlg(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
    {
        ofn.hwndOwner = hwnd;
        ofn.lpstrFile = pstrFileName;  //全路径文件名
        ofn.lpstrFileTitle = pstrTitleName;//文件名(含扩展名)
        ofn.Flags = OFN_OVERWRITEPROMPT;
        return GetSaveFileName(&ofn);
    }
    BOOL PopFileRead(HWND hwndEdit, PTSTR pstrFileName)
    {
        BYTE bySwap;
        DWORD dwBytesRead;
        HANDLE hFile;
        int iFileLength, iUniTest;
        PBYTE pBuffer, pText, pConv;
        //打开文件
        hFile = CreateFile(pstrFileName, GENERIC_READ,
                           FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
        if (INVALID_HANDLE_VALUE == hFile)
        {
            return FALSE;
        }
        //获得文件总字节数
        iFileLength = GetFileSize(hFile, NULL);
        pBuffer = malloc(iFileLength + 2);//多出两个字节存放两个
        //读文件到缓冲区,并在文件末尾放结束符
        ReadFile(hFile, pBuffer, iFileLength, &dwBytesRead, NULL);
        CloseHandle(hFile);
        pBuffer[iFileLength] = '';
        pBuffer[iFileLength + 1] = '';
        //测试文本是否是Unicode编码,前两个字节为0xFEFF或0xFFFE
        //IS_TEXT_UNICODE_SIGNATURE——0xFEFF(小端:高高低低)
        //IS_TEXT_UNICODE_REVERSE_SIGNATURE——0xFFFE(大端)
        iUniTest = IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE;
    
        if (IsTextUnicode(pBuffer, iFileLength, &iUniTest))  //最3个参数是个in/out参数。会满足的那个条件传给iUniTest
        {
            pText = pBuffer + 2; //跳过前两个字节,指向正文部分
            iFileLength -= 2;
            if (iUniTest & IS_TEXT_UNICODE_REVERSE_SIGNATURE)  //大端存储,调换字节顺序
            {
                for (int i = 0; i < iFileLength / 2; i++)
                {
                    bySwap = pText[2 * i];
                    pText[2 * i] = pText[2 * i + 1];
                    pText[2 * i + 1] = bySwap;
                }
            }
            //为可能的字符串转换分配内存
            pConv = malloc(iFileLength + 2);
    #ifndef UNICODE   //Edit控件使用非Unicode,则显示之前将Unicode文本转化为多字节文本
            WideCharToMultiByte(CP_ACP, 0, (PTSTR)pText, -1, pConv, iFileLength + 2, NULL, NULL); //共iFileLength+2字节,含2个
    #else   //Edit控件是Unicode,则直接拷贝文本
            lstrcpy((PTSTR)pConv, (PTSTR)pText);
    #endif
        } else  //非Unicode文件
        {
            pText = pBuffer;
            pConv = malloc(2 * iFileLength + 2); //ASCII转Unicode,需2倍的空间。额外加两个。
    
            //为可能字符串转换分配内存
    #ifdef UNICODE   //Edit控件使用Unicode,则显示之前,将多字节文本转化为Unicode文本
            MultiByteToWideChar(CP_ACP, 0, pText, -1, (PTSTR)pConv, iFileLength + 1); //找到时,总共iFileLength+1个字符(含)
    #else   //Edit控件是使用ASCII,则直接拷贝文本
            lstrcpy((PTSTR)pConv, (PTSTR)pText);
    #endif
        }
        SetWindowText(hwndEdit, (PTSTR)pConv);
        free(pBuffer);
        free(pConv);
        return TRUE;
    }
    BOOL PopFileWrite(HWND hwndEdit, PTSTR pstrFileName)
    {
        DWORD   dwBytesWritten;
        HANDLE  hFile;
        int iLength;
        PTSTR pstBuffer;
        WORD wByteOrderMark = 0xFEFF; //小端模式时,前两个字节被写入FF FE。大端时被写入FE FF
        //打开文件,必要时可创建文件
        hFile = CreateFile(pstrFileName, GENERIC_WRITE, 0,
                           NULL, CREATE_ALWAYS, 0, NULL);
        if (INVALID_HANDLE_VALUE == hFile)
            return FALSE;
        //获取编辑框中的字符个数,并分配内存
        iLength = GetWindowTextLength(hwndEdit);
        pstBuffer = (PTSTR)malloc((iLength + 1)*sizeof(TCHAR));
    
        if (!pstBuffer)
        {
            CloseHandle(hFile);
            return FALSE;
        }
        //如果编辑框使用Unicode编码,则写入Unicode字节序
    #ifdef UNICODE
        //文件的指针会移动到文件新增加的字节的最后(当然这是在文件打开的方式不是FILE_FLAG_OVERLAPPED)。
        WriteFile(hFile, &wByteOrderMark, 2, &dwBytesWritten, NULL);
    #endif
        //获取编辑框中的文本,并输出到文件
        GetWindowText(hwndEdit, pstBuffer, iLength + 1); //
        WriteFile(hFile, pstBuffer, iLength*sizeof(TCHAR), &dwBytesWritten, NULL);
        if ((iLength*sizeof(TCHAR)) != (int)dwBytesWritten)
        {
            CloseHandle(hFile);
            free(pstBuffer);
            return FALSE;
        }
        CloseHandle(hFile);
        free(pstBuffer);
        return TRUE;
    }

    //PopFind.c

    #include <windows.h>
    #include <tchar.h>
    #include "CommFunc.h"
    #define  MAX_STRING_LEN 256
    static TCHAR szFindText[MAX_STRING_LEN];
    static TCHAR szReplText[MAX_STRING_LEN];
    HWND PopFindFindDlg(HWND hwnd)
    {
        static FINDREPLACE fr; //对非模态对话框,这时必须是静态变量!
        fr.lStructSize = sizeof(FINDREPLACE);
        fr.hwndOwner = hwnd;
        fr.hInstance = NULL;
        fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
        fr.lpstrFindWhat = szFindText;
        fr.lpstrReplaceWith = NULL;
        fr.wFindWhatLen = MAX_STRING_LEN;
        fr.wReplaceWithLen = 0;
        fr.lCustData = 0;
        fr.lpfnHook = NULL;
        fr.lpTemplateName = NULL;
        return FindText(&fr);
    }
    HWND PopFindReplaceDlg(HWND hwnd)
    {
        static FINDREPLACE fr; //对非模态对话框,这时必须是静态变量!
        fr.lStructSize = sizeof(FINDREPLACE);
        fr.hwndOwner = hwnd;
        fr.hInstance = NULL;
        fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
        fr.lpstrFindWhat = szFindText;
        fr.lpstrReplaceWith = szReplText;
        fr.wFindWhatLen = MAX_STRING_LEN;
        fr.wReplaceWithLen = MAX_STRING_LEN;
        fr.lCustData = 0;
        fr.lpfnHook = NULL;
        fr.lpTemplateName = NULL;
        return ReplaceText(&fr);
    }
    BOOL PopFindFindText(HWND hwndEdit, int* piSearchOffset, LPFINDREPLACE pfr)
    {
        int iLength, iPos;
        PTSTR pstrDoc, pstrPos; //文件指针和当前位置指针
    
        //读取编辑框内容
        iLength = GetWindowTextLength(hwndEdit); //文本总字符个数
        pstrDoc = (PTSTR)malloc((iLength + 1)*sizeof(TCHAR)); //加个
    
        if (NULL == pstrDoc)
            return FALSE;
        GetWindowText(hwndEdit, pstrDoc, iLength + 1);
        //查找字符串:_tcsstr:字符串2在字符串1中首次出现的位置,未出现返回NULL值
        pstrPos = _tcsstr(pstrDoc + *piSearchOffset, pfr->lpstrFindWhat);
    
        //如果找不到,返回FALSE
        if (pstrPos == NULL) return FALSE;
        //找到字符串,将偏移设置到新的位置
        iPos = pstrPos - pstrDoc;
        *piSearchOffset = iPos + lstrlen(pfr->lpstrFindWhat); //偏移设到找到的字符串的后面。
        free(pstrDoc);
        //选中找到的文本
        SendMessage(hwndEdit, EM_SETSEL, iPos, *piSearchOffset);
        SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0);//可视窗口滚动到插入符号的位置,以便可见找到的文本。
        return TRUE;
    }
    BOOL PopFindNextText(HWND hwndEdit, int* piSearchOffset)
    {
        FINDREPLACE fr;
        fr.lpstrFindWhat = szFindText;
        return PopFindFindText(hwndEdit, piSearchOffset, &fr);
    }
    BOOL PopFindReplaceText(HWND hwndEdit, int* piSearchOffset, LPFINDREPLACE pfr)
    {
        //查找文本
        if (!PopFindFindText(hwndEdit, piSearchOffset, pfr))
            return FALSE;
        //替换文本:wParam=0,表示不可撤消,为1可撤消。lParam指向替换字符串
        SendMessage(hwndEdit, EM_REPLACESEL, 0, (LPARAM)pfr->lpstrReplaceWith);
        return TRUE;
    }
    BOOL PopFindValidFind(void)
    {
        return  *szFindText != '';  //没输入查找文本时,是无效的查找。
    }

    //PopFont.c

    /*------------------------------------------
    POPFONT.C ——Popup Editor Font Functions
    -------------------------------------------*/
    #include <windows.h>
    #include "CommFunc.h"
    static LOGFONT logfont;
    static HFONT hFont;
    BOOL PopFontChooseFont(HWND hwnd)
    {
        CHOOSEFONT cf;
        ZeroMemory(&cf, sizeof(cf));
        cf.lStructSize = sizeof(CHOOSEFONT);
        cf.hwndOwner = hwnd;
        cf.lpLogFont = &logfont;
        cf.iPointSize = 0;     //选择的字体的大小,单位是1/10磅
        cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS; //用logfont初始化对话框,屏幕字体、效果复选框
        cf.nFontType = 0;//所选字体的
        return ChooseFont(&cf);
    }
    void PopFontInitialize(HWND hwndEdit)
    {
        GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), (PTSTR)&logfont); //获取系统字体
        hFont = CreateFontIndirect(&logfont);
        SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0);  //初始化对话框为系统字体
    }
    void PopFontSetFont(HWND hwndEdit)
    {
        HFONT hFontNew;
        RECT  rect;
        hFontNew = CreateFontIndirect(&logfont);
        SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFontNew, 0);  //改变对话框字体
        DeleteObject(hFont);
        hFont = hFontNew;
        GetClientRect(hwndEdit, &rect);
        InvalidateRect(hwndEdit, &rect, TRUE);
    }
    void PopFontDeinitialize(void)
    {
        DeleteObject(hFont);
    }

    //resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ 生成的包含文件。
    // 供 PopPad3.rc 使用
    //
    #define IDM_FILE_NEW                    40001
    #define IDM_FILE_OPEN                   40002
    #define IDM_FILE_SAVE                   40003
    #define IDM_FILE_SAVE_AS                40004
    #define IDM_FILE_PRINT                  40005
    #define IDM_APP_EXIT                    40006
    #define IDM_EDIT_UNDO                   40007
    #define IDM_EDIT_CUT                    40008
    #define IDM_EDIT_COPY                   40009
    #define IDM_EDIT_PASTE                  40010
    #define IDM_EDIT_CLEAR                  40011
    #define IDM_EDIT_SELECT_ALL             40012
    #define IDM_HELP_HELP                   40013
    #define IDM_APP_ABOUT                   40014
    #define IDM_SEARCH_FIND                 40015
    #define IDM_SEARCH_NEXT                 40016
    #define IDM_SEARCH_REPLACE              40017
    #define IDM_FORMAT_FONT                 40018
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        105
    #define _APS_NEXT_COMMAND_VALUE         40051
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif

    //PopPad3.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    #define APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "winres.h"
    /////////////////////////////////////////////////////////////////////////////
    #undef APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    // 中文(简体,中国) resources
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
    LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
    #ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    1 TEXTINCLUDE
    BEGIN
    "resource.h"
    END
    2 TEXTINCLUDE
    BEGIN
    "#include ""winres.h""
    "
    ""
    END
    3 TEXTINCLUDE
    BEGIN
    "
    "
    ""
    END
    #endif    // APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //
    POPPAD3 MENU
    BEGIN
    POPUP "&File"
    BEGIN
    MENUITEM "&New", IDM_FILE_NEW
    MENUITEM "&Open", IDM_FILE_OPEN
    MENUITEM "&Save", IDM_FILE_SAVE
    MENUITEM "Save &As...", IDM_FILE_SAVE_AS
    MENUITEM SEPARATOR
    MENUITEM "&Print", IDM_FILE_PRINT
    MENUITEM SEPARATOR
    MENUITEM "E&xit", IDM_APP_EXIT
    END
    POPUP "&Edit"
    BEGIN
    MENUITEM "&Undo	Ctrl+Z", IDM_EDIT_UNDO
    MENUITEM SEPARATOR
    MENUITEM "Cu&t	Ctrl+X", IDM_EDIT_CUT
    MENUITEM "&Copy	Ctrl+C", IDM_EDIT_COPY
    MENUITEM "&Paste	Ctrl+V", IDM_EDIT_PASTE
    MENUITEM "De&lete	Del", IDM_EDIT_CLEAR
    MENUITEM SEPARATOR
    MENUITEM "&Select All", IDM_EDIT_SELECT_ALL
    END
    POPUP "&Search"
    BEGIN
    MENUITEM "&Find...	Ctrl+F", IDM_SEARCH_FIND
    MENUITEM "Find &Next	F3", IDM_SEARCH_NEXT
    MENUITEM "&Replace...	Ctrl+R", IDM_SEARCH_REPLACE
    END
    POPUP "F&ormat"
    BEGIN
    MENUITEM "&Font...", IDM_FORMAT_FONT
    END
    POPUP "&Help"
    BEGIN
    MENUITEM "&Help...", IDM_HELP_HELP
    MENUITEM "&About PopPad3...", IDM_APP_ABOUT
    END
    END
    /////////////////////////////////////////////////////////////////////////////
    //
    // Icon
    //
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    POPPAD3                 ICON                    "POPPAD3.ICO"
    /////////////////////////////////////////////////////////////////////////////
    //
    // Accelerator
    //
    POPPAD3 ACCELERATORS
    BEGIN
    VK_DELETE, IDM_EDIT_CLEAR, VIRTKEY, NOINVERT
    VK_INSERT, IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
    VK_DELETE, IDM_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
    VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
    VK_BACK, IDM_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
    VK_F1, IDM_HELP_HELP, VIRTKEY, NOINVERT
    "^C", IDM_EDIT_COPY, ASCII, NOINVERT
    "^V", IDM_EDIT_PASTE, ASCII, NOINVERT
    "^X", IDM_EDIT_CUT, ASCII, NOINVERT
    "^Z", IDM_EDIT_UNDO, ASCII, NOINVERT
    END
    #endif    // 中文(简体,中国) resources
    /////////////////////////////////////////////////////////////////////////////
    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED

    11.3.5 只调用一个函数

    (1)CHOOSECOLOR结构

    字段

    说明

    lStructSize

    结构体大小

    hwndOwner

    所属窗口,不能为NULL,必须设置。因为对话框是非模态的,要向父窗口发送查找或替换的消息。

    rgbResult

    用户选择的颜色值。

    lpCustColors

    用户自定义颜色缓冲区,指向一个16个双字长度的缓冲区,定义16种自定义颜色。该指针不能为NULL,必须分配16个双字长的缓冲区!

    Flags

    ①CC_FULLOPEN:对话框显示右边的扩展部分。

    ②CC_PREVENTFULLOPEN:不允许展开右边扩展的部分。

    ③CC_RGBINIT:用rgbResult的值初始化选择框中的颜色。

    (2)ChooseColor函数调用颜色对话框。
     【Colors3程序】
    效果图

    /*----------------------------------------------
    COLORS3.C -- Version using Common Dialog Box
    (c) Charles Petzold, 1998
    ----------------------------------------------*/
    #include <windows.h>
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        static CHOOSECOLOR cc;
        static COLORREF    crCustColors[16];
        cc.lStructSize = sizeof(CHOOSECOLOR);
        cc.hwndOwner = NULL;
        cc.hInstance = NULL;
        cc.rgbResult = RGB(0x80, 0x80, 0x80);
        cc.lpCustColors = crCustColors; //必须指定!
        cc.Flags = CC_RGBINIT | CC_FULLOPEN;
        cc.lCustData = 0;
        cc.lpfnHook = NULL;
        cc.lpTemplateName = NULL;
        return ChooseColor(&cc);
    }
  • 相关阅读:
    弹出框位置设置
    Spring Boot 发布 jar 包转为 war 包秘籍
    Oracle 动态sql小例子
    [转]ORACLE EXECUTE IMMEDIATE 小结
    [转]Java web 开发 获取用户ip
    SQLServer2008 使用sql语句访问excel数据
    Oracle 循环调用存储过程
    JavaScript 判断手机端操作系统(Andorid/IOS)
    Oracle 当输入参数允许为空时
    Oracle 生成数据字典
  • 原文地址:https://www.cnblogs.com/5iedu/p/4695106.html
Copyright © 2011-2022 走看看