第11章 對話框_11.3 通用對話框

11.3 通用對話框css

11.3.1 完善POPADwindows

(1)通用對話框:#include<commdlg.h>app

(2)OPENFILENAME結構less

字段ide

含義函數

備註測試

lStructSize字體

結構體的大小ui

 

hwndOwner編碼

所屬窗口,能夠爲NULL

 

hInstance

 

 

lpstrFilter

文件篩選字符串

 

TCHAR szFilter[] =

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

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

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

①可由多組內容組成,每組包含一個說明字符串(紅色)和一個篩選字符串(藍色),字符串的最後用兩個\0結束。

②篩選字符串能夠同時指出多個擴展名,中間用分號隔開,如:*.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;\dir1\file.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爲結束符的字符串,而且自動計算長度(含\0)。

lpMultiByteStr

接收被轉換字符串的緩衝區

cchMultiByte

lpMultiByteStr指向的緩衝區最大值(用字節來計量)

lpDefaultChar

遇到一個不能轉換的寬字符,函數便會使用該參數指向的字符。

pfUsedDefaultChar

只要遇到任何一個不能被轉換的字符,就會被函數設爲TRUE。

②MultiByteToWideChar——將多字節字符串轉爲Unicode字符串

字段

功能

CodePage

用來標記與一個多字節字符串相關的代碼頁

dwFlags

進行額外的控制,會影響使用了讀音符號(好比重音)的字符

lpWideCharStr

轉換爲寬字節字符串的緩衝區

cchWideChar

lpWideCharStr指向的緩衝區的字符個數,若是-1,字符串將被設定爲以NULL爲結束符的字符串,而且自動計算長度(含\0)。

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("\0")); //清除編輯框內容
            szFileName[0] = '\0';
            szTitleName[0] = '\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] = '\0';
                    szTitleName[0] = '\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("\0"));
            }

            //用戶點擊了「替換所有」
            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)\0*.txt\0")\
        TEXT("AscII Files(*.ASC)\0*.asc\0")\
        TEXT("ALL Files(*.*)\0*.*\0\0");
    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);//多出兩個字節存放兩個\0
    //讀文件到緩衝區,並在文件末尾放\0結束符
    ReadFile(hFile, pBuffer, iFileLength, &dwBytesRead, NULL);
    CloseHandle(hFile);
    pBuffer[iFileLength] = '\0';
    pBuffer[iFileLength + 1] = '\0';
    //測試文本是不是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個\0
#else   //Edit控件是Unicode,則直接拷貝文本
        lstrcpy((PTSTR)pConv, (PTSTR)pText);
#endif
    } else  //非Unicode文件
    {
        pText = pBuffer;
        pConv = malloc(2 * iFileLength + 2); //ASCII轉Unicode,需2倍的空間。額外加兩個\0。

        //爲可能字符串轉換分配內存
#ifdef UNICODE   //Edit控件使用Unicode,則顯示以前,將多字節文本轉化爲Unicode文本
        MultiByteToWideChar(CP_ACP, 0, pText, -1, (PTSTR)pConv, iFileLength + 1); //找到\0時,總共iFileLength+1個字符(含\0)
#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); //含\0
    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)); //加個\0

    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 != '\0';  //沒輸入查找文本時,是無效的查找。
}

//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\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
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\tCtrl+Z", IDM_EDIT_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
MENUITEM "De&lete\tDel", IDM_EDIT_CLEAR
MENUITEM SEPARATOR
MENUITEM "&Select All", IDM_EDIT_SELECT_ALL
END
POPUP "&Search"
BEGIN
MENUITEM "&Find...\tCtrl+F", IDM_SEARCH_FIND
MENUITEM "Find &Next\tF3", IDM_SEARCH_NEXT
MENUITEM "&Replace...\tCtrl+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);
}
相關文章
相關標籤/搜索