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); }