第259章 ツールチップの復習なと


第178章から新しいコモンコントロールに ついて少しずつやってきましたが、ツールチップについてはまだ解説していませんでした。 今回は、とりあえず今まで作ってきたプログラムに従来型のツールチップをつけてみます。 それと、アクセラレータキーについては第43章で解説したきり登場してきていないので これもつけてみます。

では、早速プログラムを見てみましょう。

// mailslot10.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "新規作成(&N)...\tCtrl + N", IDM_NEW MENUITEM "開く(&O)...\tCtrl + O", IDM_OPEN MENUITEM "上書き保存(&S)\tCtrl + S", IDM_SAVE MENUITEM "名前を付けて保存(&A)...", IDM_SAVEAS MENUITEM SEPARATOR MENUITEM "タスクトレーに格納(&T)", IDM_TASK MENUITEM SEPARATOR MENUITEM "終了(&X)...\tShift + Ctrl + Z", IDM_END END POPUP "編集(&E)" BEGIN MENUITEM "元に戻す(&U)\tCtrl + Z", IDM_UNDO, GRAYED MENUITEM SEPARATOR MENUITEM "切り取り(&T)\tCtrl + X", IDM_CUT, GRAYED MENUITEM "コピー(&C)\tCtrl + C", IDM_COPY, GRAYED MENUITEM "張り付け(&P)\tCtrl + V", IDM_PASTE, GRAYED MENUITEM "削除(&D)\tDel", IDM_DELETE, GRAYED MENUITEM SEPARATOR MENUITEM "すべて選択(&L)\tCtrl + A", IDM_ALL END POPUP "表示(&V)" BEGIN MENUITEM "書き込み用ウィンドウ", IDM_WRITE MENUITEM "ツールバー", IDM_TOOL END POPUP "オプション(&O)" BEGIN MENUITEM "IDを表示する(&I)", IDM_ID MENUITEM SEPARATOR MENUITEM ".chtを関連づける(&R)", IDM_REG END END RTRAYMENU MENU DISCARDABLE BEGIN POPUP " ダミーです" BEGIN MENUITEM "タスクトレーから出す", IDM_SHOW MENUITEM "終了", IDM_END END END ///////////////////////////////////////////////////////////////////////////// // // Dialog // MAILSLOTNAME DIALOG DISCARDABLE 0, 0, 118, 61 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "メールスロット名" FONT 9, "MS Pゴシック" BEGIN EDITTEXT IDC_EDIT1,7,19,104,16,ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,34,39,50,14 LTEXT "自分のメールスロットの名前",IDC_STATIC,7,7,83,8 END MYWRITE DIALOG DISCARDABLE 0, 0, 163, 153 STYLE DS_MODALFRAME | WS_CHILD FONT 9, "MS Pゴシック" BEGIN EDITTEXT IDC_EDIT3,70,23,86,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,70,44,86,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT1,7,69,149,56,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN DEFPUSHBUTTON "送信",IDOK,56,132,50,14 LTEXT "相手のメールスロット",IDC_STATIC,7,45,62,8 LTEXT "送信先コンピュータ",IDC_STATIC,7,25,56,8 CONTROL "他のコンピュータにメッセージを送る",IDC_CHECK1,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,7,119,10 END ///////////////////////////////////////////////////////////////////////////// // // Icon // MYICON ICON DISCARDABLE "myicon.ico" ///////////////////////////////////////////////////////////////////////////// // // Accelerator // MYACCEL ACCELERATORS DISCARDABLE BEGIN "A", IDM_ALL, VIRTKEY, CONTROL, NOINVERT "C", IDM_COPY, VIRTKEY, CONTROL, NOINVERT "N", IDM_NEW, VIRTKEY, CONTROL, NOINVERT "O", IDM_OPEN, VIRTKEY, CONTROL, NOINVERT "S", IDM_SAVE, VIRTKEY, CONTROL, NOINVERT "V", IDM_PASTE, VIRTKEY, CONTROL, NOINVERT VK_DELETE, IDM_DELETE, VIRTKEY, NOINVERT "X", IDM_CUT, VIRTKEY, CONTROL, NOINVERT "Z", IDM_UNDO, VIRTKEY, CONTROL, NOINVERT "Z", IDM_END, VIRTKEY, SHIFT, CONTROL, NOINVERT END ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN IDS_TIPS_COPY "選択された文字列をコピーします" IDS_TIPS_NEW "新規ファイルを作成します" IDS_TIPS_OPEN "ファイルをオープンします" IDS_TIPS_SAVE "上書き保存をします" IDS_TIPS_PASTE "クリップボードにある文字列を張り付けます" IDS_TIPS_DELETE "選択された文字列を削除します" IDS_TIPS_CUT "選択された文字列を切り取ってクリップボードに送ります" IDS_TIPS_UNDO "編集を元に戻します" END

メニュー項目の後ろにアクセラレーターキーを表示しておきます。「終了」には 「Shift + Ctrl + Z」を割り当ててみました。本来何も割り当てなくても「Alt + F4」で 終了になります。別なキーを割り当てると、どちらも有効となります。

ストリングテーブルにツールチップ表示用の文字列を用意しておきます。

// mailslot10.cpp #ifndef STRICT #define STRICT #endif #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include "resource.h" #define MYMSG_TRAY WM_USER #define ID_MYEDIT 100 #define ID_MYTRAY 101 #define ID_TOOL1 102 #define ID_TOOL2 103 #define ID_REBAR 104 #define ID_STATIC 105 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyNameProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyWriteProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyEditProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); DWORD WINAPI ReadFunc(LPVOID); HANDLE MakeMySlot(HWND, BOOL *); void MyTaskTray(HWND, PNOTIFYICONDATA); int MakeRTrayMenu(HWND); int SaveAsMyFile(HWND); int OverWriteMyFile(HWND); int OpenMyFile(HWND); int OpenMyFile2(HWND); int MyReg(void); HWND MakeMyToolbar(HWND, int, TBBUTTON *, int); int MakeNewFile(HWND); int CheckMyMenu(HWND); BOOL CanPaste(HWND); char szClassName[] = "mailslot10"; //ウィンドウクラス char szMailSlot[128];//メールスロットの名前(フルパス付き) char szSlotName[64];//メールスロットの名前(パスなし) HANDLE hSlot; HINSTANCE hInst; HWND hMainEdit; BOOL bID = FALSE;//メッセージIDを表示するかどうか BOOL bIsTask = FALSE;//タスクトレーに格納されているかどうか HWND hWriteDlg;//書き込み用モードレスダイアログボックス int DlgX, DlgY;//書き込み用ダイアログの大きさ int RebarY;//レバーコントロールの高さ int ClientX, ClientY;//親ウィンドウのクライアント領域の大きさ BOOL bWriteDlg = FALSE;//書き込み用ダイアログが表示されいるかどうか char szFileName[MAX_PATH];//パス付きファイル名 char szFile[64];//ファイルタイトル BOOL bCmdLine;//コマンドライン引数があるかどうか WNDPROC Org_EditProc;//エディットコントロールのオリジナルプロシージャ HWND hTool1, hTool2; BOOL bTool = TRUE;//ツールバーが表示されているかどうか HACCEL hAccel;//アクセラレータハンドル HWND hParent;//親ウインドウのハンドル TBBUTTON tbButton1[] = { {STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_FILEOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, }; TBBUTTON tbButton2[] = { {STD_COPY, IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_CUT, IDM_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_PASTE, IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_DELETE, IDM_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, {STD_UNDO, IDM_UNDO, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0}, };

アクセラレーターハンドルと親ウィンドウのハンドルをグローバル変数に持ってきました。

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; hInst = hCurInst; if (strcmp(lpsCmdLine, "") != 0) { strcpy(szFileName, lpsCmdLine); GetFileTitle(lpsCmdLine, szFile, sizeof(szFile)); bCmdLine = TRUE; } if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; hAccel = LoadAccelerators(hCurInst, "MYACCEL"); if (hAccel == NULL) MessageBox(NULL, "アクセラレータテープルエラー", "Error", MB_OK); if (hParent == NULL) MessageBox(NULL, "親ウィンドウのハンドルが不正です", "Error", MB_OK); while (GetMessage(&msg, NULL, 0, 0)) { if ((!TranslateAccelerator(hParent, hAccel, &msg))) { if (hWriteDlg == 0 || !IsDialogMessage(hWriteDlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } MessageBox(NULL, "メッセージループを抜けました", "OK", MB_OK); return msg.wParam; }

アクセラレーターキーを登録するには、LoadAcceleratorsでテーブルをロードして TranslateAcceleratorでアクセラレーターキーを翻訳してWM_COMMANDメッセージなどに 変換します。この時変換したメッセージの行き先を指定するため親ウィンドウのハンドルが 必要です。この関数が実行されるときにはすでにInitInstance関数が実行されていて 親のハンドルが確定しています。

//ウィンドウ・クラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst;//インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MYMENU"; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = LoadIcon(hInst, "MYICON");//アイコン return (RegisterClassEx(&wc)); }

ここは、今まで通りです。

//ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるメールスロット", //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 600, //幅 309, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; hParent = hWnd;//グローバル変数にコピーしておく ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }

親ウィンドウのハンドルをグローバル変数にコピーしておきます。

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; static BOOL bEnd; static HANDLE hThread; static HMENU hMenu; MENUITEMINFO mi; static NOTIFYICONDATA ni; RECT rc; MINMAXINFO *lpmm; INITCOMMONCONTROLSEX ic; static HWND hRebar, hStatic; REBARINFO ri; REBARBANDINFO rbinfo; LPNMTTDISPINFO lpnmttdi; switch (msg) { case WM_CREATE: ic.dwSize = sizeof(INITCOMMONCONTROLSEX); ic.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES; InitCommonControlsEx(&ic); hMenu = GetMenu(hWnd); hRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_BANDBORDERS | RBS_VARHEIGHT, 0, 0, 0, 0, hWnd, (HMENU)ID_REBAR, hInst, NULL); GetWindowRect(hRebar, &rc); RebarY = rc.bottom - rc.top; hStatic = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE | SS_SUNKEN, 0, 0, 0, 0, hWnd, (HMENU)ID_STATIC, hInst, NULL); hTool1 = MakeMyToolbar(hRebar, 3, tbButton1, ID_TOOL1); hTool2 = MakeMyToolbar(hRebar, 5, tbButton2, ID_TOOL2); if (!bCmdLine) { EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_GRAYED); SendMessage(hTool1, TB_ENABLEBUTTON, (WPARAM)IDM_SAVE, (LPARAM)MAKELONG(FALSE, 0)); } hMainEdit = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL, 0, RebarY, 0, 0, hWnd, (HMENU)ID_MYEDIT, hInst, NULL); memset(&ri, 0, sizeof(REBARINFO)); memset(&rbinfo, 0, sizeof(REBARBANDINFO)); ri.cbSize = sizeof(REBARINFO); ri.fMask = 0; ri.himl = NULL; SendMessage(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri); rbinfo.cbSize = sizeof(REBARBANDINFO); rbinfo.fMask = RBBIM_TEXT | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; rbinfo.fStyle = RBBS_CHILDEDGE; rbinfo.lpText = "ファイル"; rbinfo.hwndChild = hTool1; rbinfo.cxMinChild = 0; rbinfo.cyMinChild = 25; GetWindowRect(hTool1, &rc); rbinfo.cx = 120; SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbinfo); GetWindowRect(hRebar, &rc); rbinfo.lpText = "編集"; rbinfo.hwndChild = hTool2; rbinfo.cxMinChild = 0; rbinfo.cyMinChild = 25; rbinfo.cx = (rc.right - rc.left) - rbinfo.cx; SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbinfo); Org_EditProc = (WNDPROC)GetWindowLong(hMainEdit, GWL_WNDPROC); SetWindowLong(hMainEdit, GWL_WNDPROC, (LONG)MyEditProc); DialogBox(hInst, "MAILSLOTNAME", hWnd, (DLGPROC)MyNameProc); bEnd = FALSE; hThread = MakeMySlot(hWnd, &bEnd); if (bCmdLine) { if (OpenMyFile2(hWnd) == 0) { EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool1, TB_ENABLEBUTTON, (WPARAM)IDM_SAVE, (LPARAM)MAKELONG(TRUE, 0)); } } SetFocus(hMainEdit); CheckMyMenu(hMainEdit); memset(&mi, 0, sizeof(MENUITEMINFO)); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_STATE; mi.fState = MFS_CHECKED; SetMenuItemInfo(hMenu, IDM_TOOL, FALSE, &mi); break; case WM_SIZE: ClientX = LOWORD(lp); ClientY = HIWORD(lp); MoveWindow(hStatic, 0, 0, ClientX, 2, TRUE); SendMessage(hRebar, WM_SIZE, wp, lp); if (bTool) { GetWindowRect(hRebar, &rc); RebarY = rc.bottom - rc.top; } if (!bWriteDlg) { MoveWindow(hMainEdit, 0, RebarY + 2, ClientX, ClientY - RebarY - 2, TRUE); } else { MoveWindow(hMainEdit, 0, RebarY + 2, ClientX - DlgX, ClientY - RebarY - 2, TRUE); MoveWindow(hWriteDlg, ClientX - DlgX, RebarY + 2, DlgX, ClientY - RebarY - 2, TRUE); } break; case WM_GETMINMAXINFO: lpmm = (MINMAXINFO *)lp; if (bWriteDlg) { lpmm->ptMinTrackSize.y = 281 + RebarY; lpmm->ptMinTrackSize.x = 450; return 0; } else if (bTool){ lpmm->ptMinTrackSize.y = 140; lpmm->ptMinTrackSize.x = 300; } else { return (DefWindowProc(hWnd, msg, wp, lp)); } break; case MYMSG_TRAY: if (wp == ID_MYTRAY) { switch (lp) { case WM_RBUTTONDOWN: MakeRTrayMenu(hWnd); break; case WM_LBUTTONDBLCLK: bIsTask = FALSE; Shell_NotifyIcon(NIM_DELETE, &ni); ShowWindow(hWnd, SW_SHOWNORMAL); default: break; } } break; case WM_NOTIFY: switch (((LPNMHDR)lp)->code) { case TTN_GETDISPINFO: lpnmttdi = (LPNMTTDISPINFO)lp; lpnmttdi->hinst = hInst; lpnmttdi->uFlags = 0; lpnmttdi->lParam = NULL; switch (lpnmttdi->hdr.idFrom) { case IDM_NEW: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_NEW); break; case IDM_OPEN: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_OPEN); break; case IDM_SAVE: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_SAVE); break; case IDM_COPY: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_COPY); break; case IDM_CUT: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_CUT); break; case IDM_PASTE: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_PASTE); break; case IDM_UNDO: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_UNDO); break; case IDM_DELETE: lpnmttdi->lpszText = MAKEINTRESOURCE(IDS_TIPS_DELETE); break; } break; case RBN_HEIGHTCHANGE: if (bTool) { GetWindowRect(hRebar, &rc); RebarY = rc.bottom - rc.top; } MoveWindow(hMainEdit, 0, RebarY + 2, ClientX - DlgX, ClientY - RebarY - 2, TRUE); if (bWriteDlg) MoveWindow(hWriteDlg, ClientX - DlgX, RebarY + 2, DlgX, ClientY - RebarY - 2, TRUE); GetWindowRect(hWnd, &rc); MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } break; case WM_COMMAND: switch (LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; case IDM_WRITE: if (!IsWindow(hWriteDlg)) { hWriteDlg = CreateDialog(hInst, "MYWRITE", hWnd, (DLGPROC)MyWriteProc); if (hWriteDlg != NULL) { bWriteDlg = TRUE; ShowWindow(hWriteDlg, SW_SHOW); GetWindowRect(hWriteDlg, &rc); DlgX = rc.right - rc.left; DlgY = rc.bottom - rc.top; MoveWindow(hWriteDlg, ClientX - DlgX, RebarY + 2, DlgX, ClientY - RebarY - 2, TRUE); MoveWindow(hMainEdit, 0, RebarY + 2, ClientX - DlgX, ClientY - RebarY - 2, TRUE); memset(&mi, 0, sizeof(MENUITEMINFO)); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_STATE; mi.fState = MFS_CHECKED; SetMenuItemInfo(hMenu, IDM_WRITE, FALSE, &mi); GetWindowRect(hWnd, &rc); MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); } else { MessageBox(hWnd, "ダイアログボックス作成失敗です", "Error", MB_OK); return 0; } } else { DestroyWindow(hWriteDlg); bWriteDlg = FALSE; MoveWindow(hMainEdit, 0, RebarY + 2, ClientX, ClientY - RebarY - 2, TRUE); memset(&mi, 0, sizeof(MENUITEMINFO)); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_STATE; mi.fState = MFS_UNCHECKED; SetMenuItemInfo(hMenu, IDM_WRITE, FALSE, &mi); DlgX = 0; DlgY = 0; } break; case IDM_TOOL: memset(&mi, 0, sizeof(MENUITEMINFO)); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_STATE; if (bTool) { ShowWindow(hRebar, SW_HIDE); RebarY = 0; bTool = FALSE; mi.fState = MFS_UNCHECKED; SetMenuItemInfo(hMenu, IDM_TOOL, FALSE, &mi); GetWindowRect(hWnd, &rc); MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom- rc.top + 1, TRUE); } else { ShowWindow(hRebar, SW_SHOW); GetWindowRect(hRebar, &rc); RebarY = rc.bottom - rc.top; bTool = TRUE; mi.fState = MFS_CHECKED; SetMenuItemInfo(hMenu, IDM_TOOL, FALSE, &mi); GetWindowRect(hWnd, &rc); SendMessage(hWnd, WM_SIZE, (WPARAM)SIZE_RESTORED, 0); MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top - 1, TRUE); } break; case IDM_NEW: MakeNewFile(hWnd); EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_GRAYED); SendMessage(hTool1, TB_ENABLEBUTTON, (WPARAM)IDM_SAVE, (LPARAM)MAKELONG(FALSE, 0)); CheckMyMenu(hMainEdit); break; case IDM_OPEN: if (OpenMyFile(hWnd) == 0) { EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool1, TB_ENABLEBUTTON, (WPARAM)IDM_SAVE, (LPARAM)MAKELONG(TRUE, 0)); } break; case IDM_SAVE: OverWriteMyFile(hWnd); break; case IDM_SAVEAS: SaveAsMyFile(hWnd); break; case IDM_ID: memset(&mi, 0, sizeof(MENUITEMINFO)); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_STATE; if (!bID) { mi.fState = MFS_CHECKED; SetMenuItemInfo(hMenu, IDM_ID, FALSE, &mi); bID = TRUE; break; } else { mi.fState = MFS_UNCHECKED; SetMenuItemInfo(hMenu, IDM_ID, FALSE, &mi); bID = FALSE; } break; case IDM_TASK: MyTaskTray(hWnd, &ni); ShowWindow(hWnd, SW_HIDE); bIsTask = TRUE; break; case IDM_SHOW: Shell_NotifyIcon(NIM_DELETE, &ni); ShowWindow(hWnd, SW_SHOWNORMAL); bIsTask = FALSE; break; case IDM_REG: MyReg(); break; case IDM_COPY: SendMessage(hMainEdit, WM_COPY, 0, 0); CheckMyMenu(hMainEdit); break; case IDM_CUT: SendMessage(hMainEdit, WM_CUT, 0, 0); CheckMyMenu(hMainEdit); break; case IDM_PASTE: SendMessage(hMainEdit, WM_PASTE, 0, 0); break; case IDM_ALL: SendMessage(hMainEdit, EM_SETSEL, 0, -1); CheckMyMenu(hMainEdit); break; case IDM_DELETE: SendMessage(hMainEdit, WM_CLEAR, 0, 0); CheckMyMenu(hMainEdit); break; case IDM_UNDO: if (SendMessage(hMainEdit, EM_CANUNDO, 0, 0)) SendMessage(hMainEdit, WM_UNDO, 0, 0); CheckMyMenu(hMainEdit); break; } break; case WM_CLOSE: if (SendMessage(hMainEdit, EM_GETMODIFY, 0, 0)) { id = MessageBox(hWnd, "チャットの内容が更新されています。\n" "保存せずに終了しますか", "確認", MB_YESNO | MB_ICONQUESTION); if (id == IDNO) break; } id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { if (hThread) { bEnd = TRUE; WaitForSingleObject(hThread, INFINITE); if (CloseHandle(hThread)) MessageBox(hWnd, "hThreadをクローズしました", "OK", MB_OK); } if (hSlot) { if (CloseHandle(hSlot)) MessageBox(hWnd, "メールスロットを削除しました", "OK", MB_OK); } if (bIsTask) Shell_NotifyIcon(NIM_DELETE, &ni); SetWindowLong(hMainEdit, GWL_WNDPROC, (LONG)Org_EditProc); DestroyWindow(hStatic); DestroyWindow(hMainEdit); DestroyWindow(hTool1); DestroyWindow(hTool2); DestroyWindow(hRebar); if (hWriteDlg) DestroyWindow(hWriteDlg); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

いつものことですが、ウィンドウプロシージャが大変長くなってしまいました。

変更になっているのはWM_NOTIFYのところです。場合分けがごちゃごちゃになってしまうので codeで一括場合分けをしています。

ここで、ちょっと構造体と通知メッセージが今までと違うところがあります。

typedef struct tagNMTTDISPINFO { NMHDR hdr; LPTSTR lpszText; char szText[80]; HINSTANCE hinst; UINT uFlags; #if (_WIN32_IE >= 0x0300) LPARAM lParam; #endif } NMTTDISPINFO, FAR *LPNMTTDISPINFO; #define TOOLTIPTEXT NMTTDISPINFO

TOOLTIPTEXT構造体がNMTTDISPINFO構造体に取って代わられました。

また、TTN_NEEDTEXT通知メッセージがTTN_GETDISINFOに変わりました。

TTN_GETDISPINFO lpnmtdi = (LPNMTTDISPINFO)lParam; #define TTN_NEEDTEXT TTN_GETDISPINFO

これらは、単なる名称変更です。

HANDLE MakeMySlot(HWND hWnd, BOOL *lpbEnd) { HMENU hMenu; hMenu = GetMenu(hWnd); char szWinTitle[64], *szTitle_Org = "猫でもわかるメールスロット[%s][%s]"; DWORD dwThreadID; HANDLE hThread; hSlot = CreateMailslot( szMailSlot, 0, MAILSLOT_WAIT_FOREVER, NULL); if (hSlot == INVALID_HANDLE_VALUE) { MessageBox(hWnd, "メールスロット作成失敗!\n名前を変更してみてください", "Error", MB_OK); DialogBox(hInst, "MAILSLOTNAME", hWnd, (DLGPROC)MyNameProc); MakeMySlot(hWnd, lpbEnd); } else { wsprintf(szWinTitle, szTitle_Org, szSlotName, szFile); SetWindowText(hWnd, szWinTitle); hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadFunc, (LPVOID)lpbEnd, 0, &dwThreadID); if (hThread == NULL) MessageBox(hWnd, "CreateThread Error", "Error", MB_OK); } return hThread; } LRESULT CALLBACK MyNameProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { HWND hParent; static HWND hEdit; switch (msg) { case WM_INITDIALOG: hParent = GetParent(hDlg); hEdit = GetDlgItem(hDlg, IDC_EDIT1); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDOK: Edit_GetText(hEdit, szSlotName, sizeof(szSlotName)); if (strcmp(szSlotName, "") == 0) { MessageBox(hDlg, "無効な名前です", "Error", MB_OK | MB_ICONEXCLAMATION); SetFocus(hEdit); return TRUE; } wsprintf(szMailSlot, "\\\\.\\mailslot\\%s", szSlotName); EndDialog(hDlg, IDOK); return TRUE; case IDCANCEL: MessageBox(hDlg, "メールスロットの名前を決めて下さい", "注意", MB_OK | MB_ICONEXCLAMATION); return TRUE; } return FALSE; } return FALSE; } LRESULT CALLBACK MyWriteProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { static HWND hEdit, hEditTo, hCheck, hComputor; char szBuf[1024], szBuf2[1024], szTo[64], *lpszEdit, szID[32], szFrom[32]; HGLOBAL hMem; static char szShortTo[64], szComputor[64]; HANDLE hMail; DWORD dwWritten, dwTickCount; BOOL bResult; static BOOL bOtherComputor; int iSize, iLine, i; switch (msg) { case WM_INITDIALOG: hCheck = GetDlgItem(hDlg, IDC_CHECK1); hEdit = GetDlgItem(hDlg, IDC_EDIT1); hEditTo = GetDlgItem(hDlg, IDC_EDIT2); hComputor = GetDlgItem(hDlg, IDC_EDIT3); if (bOtherComputor) { Button_SetCheck(hCheck, BST_CHECKED); EnableWindow(hComputor, TRUE); } else { EnableWindow(hComputor, FALSE); } Edit_SetText(hComputor, szComputor); Edit_SetText(hEditTo, szShortTo); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDC_CHECK1: if (HIWORD(wp) == BN_CLICKED) { if (Button_GetCheck(hCheck) == BST_CHECKED) { EnableWindow(hComputor, TRUE); SetFocus(hComputor); bOtherComputor = TRUE; } else { EnableWindow(hComputor, FALSE); SetFocus(hEditTo); bOtherComputor = FALSE; } } else return FALSE; return TRUE; case IDOK: Edit_GetText(hEditTo, szShortTo, sizeof(szShortTo)); if (!bOtherComputor) { wsprintf(szTo, "\\\\.\\mailslot\\%s", szShortTo); } else { Edit_GetText(hComputor, szComputor, sizeof(szComputor)); wsprintf(szTo, "\\\\%s\\mailslot\\%s", szComputor, szShortTo); } dwTickCount = GetTickCount(); wsprintf(szID, "[Message ID = %d]\r\n", dwTickCount); Edit_GetText(hEdit, szBuf2, sizeof(szBuf2)); hMail = CreateFile(szTo, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hMail == INVALID_HANDLE_VALUE) { MessageBox(hDlg, "CreateFile Error", "Error", MB_OK); return TRUE; } strcpy(szBuf, szID); wsprintf(szFrom, "%s>", szSlotName); strcat(szBuf, szFrom); strcat(szBuf, szBuf2); bResult = WriteFile(hMail, szBuf, strlen(szBuf) + 1, &dwWritten, NULL); if (!bResult) { MessageBox(hDlg, "WriteFile Error", "Error", MB_OK); } CloseHandle(hMail); iSize = GetWindowTextLength(hMainEdit); hMem = GlobalAlloc(GHND, iSize + 1024); if (hMem == NULL) { MessageBox(hDlg, "メモリ確保に失敗しました", "Error", MB_OK); return TRUE; } lpszEdit = (char *)GlobalLock(hMem); Edit_GetText(hMainEdit, lpszEdit, iSize + 1024); strcat(lpszEdit, "\r\n"); if (bID) strcat(lpszEdit, szID); strcat(lpszEdit, szFrom); strcat(lpszEdit, szBuf2); Edit_SetText(hMainEdit, lpszEdit); iLine = Edit_GetLineCount(hMainEdit); for (i = 0; i < iLine; i++) SendMessage(hMainEdit, EM_SCROLL, (WPARAM)SB_LINEDOWN, 0); GlobalUnlock(hMem); GlobalFree(hMem); Edit_SetText(hEdit, ""); SetFocus(hEdit); return TRUE; } return FALSE; } return FALSE; } DWORD WINAPI ReadFunc(LPVOID lp) { BOOL *lpbEnd; DWORD dwNextSize, dwCount, dwRead; static char szBuf1[1024], szBuf2[1024]; HGLOBAL hMem; char *lpszTxt, *lpszFirst; int iLength, iLine, i; lpbEnd = (BOOL *)lp; while (1) { if (*lpbEnd) { MessageBox(NULL, "*lpbEndがTRUEとなりました", "LOOP END", MB_OK); break; } GetMailslotInfo(hSlot, NULL, &dwNextSize, &dwCount, NULL); if (dwNextSize != MAILSLOT_NO_MESSAGE) { while (dwCount) { ReadFile(hSlot, szBuf1, dwNextSize, &dwRead, NULL); if (strcmp(szBuf1, szBuf2) != 0) { iLength = Edit_GetTextLength(hMainEdit); hMem = GlobalAlloc(GHND, iLength + dwRead +256); if (hMem == NULL) { MessageBox(NULL, "メモリ確保に失敗しました", "Error", MB_OK); break; } lpszTxt = (char *)GlobalLock(hMem); Edit_GetText(hMainEdit, lpszTxt, iLength + dwRead +256); strcat(lpszTxt, "\r\n"); if (!bID) { lpszFirst = strstr(szBuf1, "\r\n"); strcat(lpszTxt, lpszFirst + 2); } else { strcat(lpszTxt, szBuf1); } Edit_SetText(hMainEdit, lpszTxt); SendMessage(hMainEdit, EM_SETMODIFY, (WPARAM)TRUE, 0); iLine = Edit_GetLineCount(hMainEdit); SendMessage(hMainEdit, EM_SCROLL, (WPARAM)SB_LINEDOWN, 0); iLine = Edit_GetLineCount(hMainEdit); for (i = 0; i < iLine; i++) SendMessage(hMainEdit, EM_SCROLL, (WPARAM)SB_LINEDOWN, 0); GlobalUnlock(hMem); if (GlobalFree(hMem)) { MessageBox(NULL, "メモリ解放失敗", "Error", MB_OK); break; } if (bIsTask) { MessageBox(NULL, "メッセージが来ました", "メッセージの到着", MB_OK | MB_SETFOREGROUND); } } strcpy(szBuf2, szBuf1); GetMailslotInfo(hSlot, NULL, &dwNextSize, &dwCount, NULL); } } Sleep(100); } MessageBox(NULL, "ループを抜けました", "OK", MB_OK); return 0; } void MyTaskTray(HWND hWnd, PNOTIFYICONDATA lpni) { HICON hIcon; hIcon = LoadIcon(hInst, "MYICON"); lpni->cbSize = sizeof(NOTIFYICONDATA); lpni->hIcon = hIcon; lpni->hWnd = hWnd; lpni->uCallbackMessage = MYMSG_TRAY; lpni->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; lpni->uID = ID_MYTRAY; strcpy(lpni->szTip, "猫でもわかるメールスロット"); Shell_NotifyIcon(NIM_ADD, lpni); return; } int MakeRTrayMenu(HWND hWnd) { HMENU hMenu, hSubMenu; POINT pt; hMenu = LoadMenu(hInst, "RTRAYMENU"); hSubMenu = GetSubMenu(hMenu, 0); GetCursorPos(&pt); SetForegroundWindow(hWnd); TrackPopupMenu( hSubMenu, TPM_BOTTOMALIGN, pt.x, pt.y, 0, hWnd, NULL); DestroyMenu(hMenu); return 0; } int MakeNewFile(HWND hWnd) { int id; char szWinTitle[64], *szTitle_org = "猫でもわかるメールスロット[%s][%s]"; if (SendMessage(hMainEdit, EM_GETMODIFY, 0, 0) == TRUE) { id = MessageBox( hWnd, "文書が更新されています。保存しますか?", "注意", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) SaveAsMyFile(hWnd); } wsprintf(szWinTitle, szTitle_org, szSlotName, "無題"); SetWindowText(hWnd, szWinTitle); Edit_SetText(hMainEdit, ""); return 0; } int SaveAsMyFile(HWND hWnd) { OPENFILENAME ofn; HANDLE hFile; HGLOBAL hMem; DWORD dwAccBytes; char szWinTitle[64], *szTitle_org = "猫でもわかるメールスロット[%s][%s]"; char *lpszBuf; int nLen; HMENU hMenu; nLen = GetWindowTextLength(hMainEdit); hMem = GlobalAlloc(GHND, nLen + 1); if (hMem == NULL) { MessageBox(hWnd, "メモリの確保に失敗しました", "Error", MB_OK); return -1; } lpszBuf = (char *)GlobalLock(hMem); GetWindowText(hMainEdit, lpszBuf, nLen + 1); memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFilter = "chat(*.cht)\0*.cht\0text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrFileTitle = szFile; ofn.nFilterIndex = 1; ofn.nMaxFile = sizeof(szFileName); ofn.nMaxFileTitle = sizeof(szFile); ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; ofn.lpstrDefExt = "cht"; ofn.lpstrTitle = "チャットを名前を付けて保存する"; if(GetSaveFileName(&ofn) == 0) return -1; hFile = CreateFile(szFileName, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, lpszBuf, strlen(lpszBuf) + 1, &dwAccBytes, NULL); SetEndOfFile(hFile); wsprintf(szWinTitle, szTitle_org, szSlotName, szFile); SetWindowText(hWnd, szWinTitle); if(CloseHandle(hFile) == 0) MessageBox(hWnd, "Error CloseHandle", "Error", MB_OK); if (GlobalUnlock(hMem) != 0) MessageBox(hWnd, "ロックカウントが0ではありません", "Warning", MB_OK); if (GlobalFree(hMem) != NULL) MessageBox(hWnd, "メモリ解放失敗に失敗しました", "Error", MB_OK); SendMessage(hMainEdit, EM_SETMODIFY, FALSE, 0); hMenu = GetMenu(hWnd); EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool1, TB_ENABLEBUTTON, (WPARAM)IDM_SAVE, (LPARAM)MAKELONG(TRUE, 0)); return 0; } int OverWriteMyFile(HWND hWnd) { HANDLE hFile; DWORD dwAccBytes; int nLen; HGLOBAL hMem; char *lpszBuf; nLen = GetWindowTextLength(hMainEdit); hMem = GlobalAlloc(GHND, nLen + 1); if (hMem == NULL) { MessageBox(hWnd, "メモリを確保できません", "Error", MB_OK); return -1; } lpszBuf = (char *)GlobalLock(hMem); GetWindowText(hMainEdit, lpszBuf, nLen + 1); hFile = CreateFile(szFileName, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, lpszBuf, nLen + 1, &dwAccBytes, NULL); SetEndOfFile(hFile); SendMessage(hMainEdit, EM_SETMODIFY, FALSE, 0); if (CloseHandle(hFile) == 0) { MessageBox(hWnd, "Error CloseHandle", "Error", MB_OK); return -2; } if (GlobalUnlock(hMem) != 0) MessageBox(hWnd, "ロックカウントが0ではありません", "Warning", MB_OK); if (GlobalFree(hMem) != NULL) MessageBox(hWnd, "メモリの解放に失敗しました", "Error", MB_OK); return 0; } int OpenMyFile(HWND hWnd) { int id; OPENFILENAME ofn; if(SendMessage(hMainEdit, EM_GETMODIFY, 0, 0) == TRUE) { id = MessageBox(hWnd, "チャットの内容が変更されています。保存しますか?", "注意!", MB_OKCANCEL); if (id == IDOK) SaveAsMyFile(hWnd); } memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFilter = "chat(*.cht)\0*.cht\0text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrFileTitle = szFile; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = sizeof(szFile); ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = "cht"; ofn.lpstrTitle = "ファイルオープン!"; if(GetOpenFileName(&ofn) == 0) return -1; OpenMyFile2(hWnd); return 0; } int OpenMyFile2(HWND hWnd) { HGLOBAL hMem; DWORD dwAccBytes; HMENU hMenu; HANDLE hFile; char szWinTitle[64], *szTitle_org = "猫でもわかるメールスロット[%s][%s]"; char *lpszBuf; DWORD dwSize = 0L; hFile = CreateFile(szFileName, GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); dwSize = GetFileSize(hFile, NULL); if (dwSize >= 1024*64) { MessageBox(hWnd, "ファイルサイズが大きすぎます", "Too Big File!", MB_OK); CloseHandle(hFile); dwSize = 0L; return -1; } hMem = GlobalAlloc(GHND, dwSize); if (hMem == NULL) { MessageBox(hWnd, "メモリ確保に失敗しました", "Error", MB_OK); CloseHandle(hFile); return -2; } lpszBuf = (char *)GlobalLock(hMem); SetFilePointer(hFile, 0, 0, FILE_BEGIN); ReadFile(hFile, lpszBuf, dwSize, &dwAccBytes, NULL); lpszBuf[dwAccBytes] = '\0'; Edit_SetText(hMainEdit, lpszBuf); wsprintf(szWinTitle, szTitle_org, szSlotName, szFile); SetWindowText(hWnd, szWinTitle); GlobalUnlock(hMem); GlobalFree(hMem); CloseHandle(hFile); hMenu = GetMenu(hWnd); EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | MF_ENABLED); return 0; } int MyReg() { HKEY hKey; DWORD dwDisposition; LONG lResult; char szCommand[MAX_PATH]; char szIcon[MAX_PATH]; GetCurrentDirectory(sizeof(szCommand), szCommand); strcat(szCommand, "\\"); strcat(szCommand, szClassName); strcat(szCommand, " %1"); GetCurrentDirectory(sizeof(szIcon), szIcon); strcat(szIcon, "\\"); strcat(szIcon, szClassName); strcat(szIcon, ".exe,0"); lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "MyChat\\shell\\猫チャット(&C)\\command", NULL,//予約済み "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); if (lResult != ERROR_SUCCESS) { MessageBox(NULL, "RegCreateKeyExでエラーが発生しました", "Error", MB_OK); return -1; } lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szCommand, strlen(szCommand)); RegCloseKey(hKey); lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, ".cht", NULL, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); if (lResult != ERROR_SUCCESS) { MessageBox(NULL, "RegCreateKeyExでエラーが発生しました", "Error", MB_OK); return -1; } lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)"MyChat", strlen("MyChat")); RegCloseKey(hKey); lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "MyChat\\DefaultIcon", NULL, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); if (lResult != ERROR_SUCCESS) { MessageBox(NULL, "RegCreateKeyExでエラーが発生しました", "Error", MB_OK); return -1; } lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szIcon, strlen(szIcon)); RegCloseKey(hKey); return 0; }

ここまでは、特に変更はありません。

HWND MakeMyToolbar(HWND hWnd, int n, TBBUTTON *tbButton, int id) { HWND hTool; TBADDBITMAP tbab; int stdid, i; hTool = CreateToolbarEx(hWnd, WS_VISIBLE | WS_CHILD| CCS_NODIVIDER | CCS_NORESIZE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, id , 0, NULL, NULL, tbButton, 0, 0, 0, 0, 0, sizeof(TBBUTTON)); tbab.hInst = HINST_COMMCTRL; tbab.nID = IDB_STD_SMALL_COLOR; stdid = SendMessage(hTool, TB_ADDBITMAP, n, (LPARAM)&tbab); for (i = 0; i < n; i++) tbButton[i].iBitmap += stdid; SendMessage(hTool, TB_ADDBUTTONS, n, (LONG)tbButton); SendMessage(hTool, TB_AUTOSIZE, 0, 0); return hTool; }

ツールバーのウィンドウスタイルにTBSTYLE_TOOLTIPSが加わりました。

int CheckMyMenu(HWND hWnd) { DWORD dwStart, dwEnd; HMENU hMenu; HWND hParent; hParent = GetParent(hWnd); hMenu = GetMenu(hParent); if (Edit_GetTextLength(hWnd) == 0) { EnableMenuItem(hMenu, IDM_ALL, MF_BYCOMMAND | MF_GRAYED); } else { EnableMenuItem(hMenu, IDM_ALL, MF_BYCOMMAND | MF_ENABLED); } SendMessage(hMainEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd); if (dwStart == dwEnd) { EnableMenuItem(hMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(hMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(hMenu, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(FALSE, 0)); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(FALSE, 0)); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_DELETE, (LPARAM)MAKELONG(FALSE, 0)); } else { EnableMenuItem(hMenu, IDM_COPY, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem(hMenu, IDM_CUT, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem(hMenu, IDM_DELETE, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(TRUE, 0)); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(TRUE, 0)); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_DELETE, (LPARAM)MAKELONG(TRUE, 0)); } if (SendMessage(hMainEdit, EM_GETMODIFY, 0, 0)) { EnableMenuItem(hMenu, IDM_UNDO, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(TRUE, 0)); } else { EnableMenuItem(hMenu, IDM_UNDO, MF_BYCOMMAND | MF_GRAYED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE, 0)); } if (CanPaste(hParent)) { EnableMenuItem(hMenu, IDM_PASTE, MF_BYCOMMAND | MF_ENABLED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE, 0)); } else { EnableMenuItem(hMenu, IDM_PASTE, MF_BYCOMMAND | MF_GRAYED); SendMessage(hTool2, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE, 0)); } return 0; } // サブクラス化されたエディットコントロールのプロシージャ LRESULT CALLBACK MyEditProc(HWND hEdit, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_LBUTTONUP: CheckMyMenu(hEdit); break; case WM_KEYUP: CheckMyMenu(hEdit); break; default: break; } return (CallWindowProc(Org_EditProc, hEdit, msg, wp, lp)); } BOOL CanPaste(HWND hWnd) { HANDLE hMem; if (!OpenClipboard(hWnd)) { MessageBox(hWnd, "Openclipboard 失敗", "Error", MB_OK); return FALSE; } hMem = GetClipboardData(CF_TEXT); if (hMem == NULL) { CloseClipboard(); return FALSE; } else { CloseClipboard(); return TRUE; } }

ここは、特に変更はありません。

さて、今回はアクセラレーターキーを定義して、ツールバーにツールチップを付けただけで 特に目新しいことはありませんでした。


[SDK第3部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 05/Mar/2000 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。