第148章 フラットツールバーを作る


筆者はIE3.0が出たとき以来、IE3.0のようなツールバー( マウスが近づくとボコッとボタンが盛り上がる)はどうやって SDKレベルで実現できるのかと悩みつづけていました。 MFCレベルではかなり以前よりこのツールバーの作り方の解説が 外国のホーム・ページなどに掲載されていました。 VC++6.0になってようやくSDKレベルで実現できるようになりました! したがって、今回の解説はVC++6.0以降またはそれと同等の SDKライブラリを持つ処理系でないと実現できません。



最近では良く見かける「フラットツールバー」です。 もちろん、ツールバーのカスタマイズとか、Alt(GRPG)キーを押しながら ボタンをドラッグすることもできます。



このタイプのツールバーはほとんど見かけません。 このプログラムを作った筆者も初めて見ました。 このタイプのツールバーを使ってフリーソフトなどを作ると 斬新でいいかもしれません。ただし、ボタンが使用可能か不可能かは 大変見づらいです。



これも、見かけないツールバーですね。



さて、これらのツールバーの作り方はいたって簡単です。 ツールバーのウィンドウスタイルにTBSTYLE_FLATを加えると フラットツールバーになり、TBSTYLE_TRANSPARENTを加えると ツールバーのみが透明(ボタンは従来どおり)になります。 この両方を加えると透明ツールバーとなります。 しかし、CreateToolbarExとかCreateWindowExでいきなり これらのスタイルを加えても思い通りになりません。 いったん従来どおりのスタイルでツールバーを作ってから SetWindowLongでスタイルの指定をします。

では、プログラムを見てみることにします。

// rich19.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "新規作成(&N)", IDM_NEW MENUITEM "開く(&O)", IDM_OPEN MENUITEM SEPARATOR MENUITEM "上書き保存(&S)", IDM_SAVE MENUITEM "名前をつけて保存(&A)", IDM_SAVEAS MENUITEM SEPARATOR MENUITEM "プリンターの設定(&U)", IDM_PRNSET MENUITEM "印刷(&P)", IDM_PRINT MENUITEM SEPARATOR MENUITEM "終了(&X)", IDM_END END POPUP "編集(&E)" BEGIN MENUITEM "元に戻す(&U)", IDM_UNDO MENUITEM SEPARATOR MENUITEM "横書き(&H)", IDM_HORIZONTAL MENUITEM "縦書き(&V)", IDM_VERTICAL MENUITEM SEPARATOR MENUITEM "フォントの変更(&F)", IDM_FONT POPUP "段落書式(&P)" BEGIN MENUITEM "中央揃え(&C)", IDM_CENTER MENUITEM "左揃え(&L)", IDM_LEFT MENUITEM "右揃え(&R)", IDM_RIGHT MENUITEM SEPARATOR POPUP "タブの設定(&T)" BEGIN MENUITEM "2cm毎", IDM_2CM MENUITEM "1cm毎", IDM_CM MENUITEM "0.5cm毎", IDM_05CM MENUITEM SEPARATOR MENUITEM "2インチ毎", IDM_2INCH MENUITEM "1インチ毎", IDM_INCH MENUITEM "0.5インチ毎", IDM_05INCH END MENUITEM SEPARATOR MENUITEM "段落マーク付け(&M)", IDM_NUM END MENUITEM SEPARATOR MENUITEM "コピー(&C)", IDM_COPY MENUITEM "切り取り(&T)", IDM_CUT MENUITEM "貼り付け(&P)", IDM_PASTE MENUITEM "削除(&D)", IDM_DELETE MENUITEM SEPARATOR MENUITEM "すべて選択(&L)", IDM_ALL END POPUP "表示(&V)" BEGIN MENUITEM "背景色の変更(&B)", IDM_BACKCOLOR MENUITEM "ツールバーのカスタマイズ(&C)", IDM_CUSTOMIZE MENUITEM SEPARATOR MENUITEM "ツールバー(&T)", IDM_TOOL MENUITEM "ステータスバー(&S)", IDM_STATUS MENUITEM "ルーラー(&R)", IDM_RULER MENUITEM SEPARATOR POPUP "ツールバーの外観" BEGIN MENUITEM "従来タイプ(&O)", IDM_OLD MENUITEM "フラット(&F)", IDM_FLAT MENUITEM "透明(&T)", IDM_TRANSPARENT MENUITEM "ツールバーのみ透明(&U)", IDM_TRANSPARENT2 END END POPUP "ヘルプ(&H)" BEGIN MENUITEM "バージョン情報(&A)", IDM_ABOUT MENUITEM "サポート(&S)", IDM_SUPPORT END END MYPOPUP MENU DISCARDABLE BEGIN POPUP "ダミーです" BEGIN MENUITEM "新規作成", IDM_NEW MENUITEM "開く", IDM_OPEN MENUITEM SEPARATOR MENUITEM "上書き保存", IDM_SAVE MENUITEM "名前をつけて保存", IDM_SAVEAS MENUITEM SEPARATOR MENUITEM "横書き", IDM_HORIZONTAL MENUITEM "縦書き", IDM_VERTICAL MENUITEM SEPARATOR MENUITEM "フォントの変更", IDM_FONT MENUITEM SEPARATOR MENUITEM "左揃え", IDM_LEFT MENUITEM "右揃え", IDM_RIGHT MENUITEM "中央揃え", IDM_CENTER MENUITEM SEPARATOR MENUITEM "終了", IDM_END MENUITEM SEPARATOR MENUITEM "コピー", IDM_COPY MENUITEM "切り取り", IDM_CUT MENUITEM "貼り付け", IDM_PASTE MENUITEM "削除", IDM_DELETE MENUITEM "元に戻す", IDM_UNDO MENUITEM SEPARATOR MENUITEM "印刷", IDM_PRINT MENUITEM "プリンタの設定", IDM_PRNSET MENUITEM SEPARATOR MENUITEM "すべて選択", IDM_ALL MENUITEM SEPARATOR MENUITEM "背景色の変更", IDM_BACKCOLOR MENUITEM SEPARATOR POPUP "タブの設定" BEGIN MENUITEM "2cm毎", IDM_2CM MENUITEM "1cm毎", IDM_CM MENUITEM "0.5cm毎", IDM_05CM MENUITEM SEPARATOR MENUITEM "2インチ毎", IDM_2INCH MENUITEM "1インチ毎", IDM_INCH MENUITEM "0.5インチ毎", IDM_05INCH END MENUITEM SEPARATOR MENUITEM "段落マーク付け", IDM_NUM MENUITEM SEPARATOR MENUITEM "ツールバー", IDM_TOOL MENUITEM "ステータスバー", IDM_STATUS MENUITEM "ルーラー", IDM_RULER MENUITEM SEPARATOR POPUP "ツールバーの外観" BEGIN MENUITEM "従来タイプ", IDM_OLD MENUITEM "フラットタイプ", IDM_FLAT MENUITEM "透明タイプ", IDM_TRANSPARENT MENUITEM "ボタンのみ透明", IDM_TRANSPARENT2 END END END ///////////////////////////////////////////////////////////////////////////// // // Toolbar // ID_MYTOOLBAR TOOLBAR DISCARDABLE 16, 15 BEGIN BUTTON IDM_VERTICAL BUTTON IDM_HORIZONTAL BUTTON IDM_LEFT BUTTON IDM_CENTER BUTTON IDM_RIGHT BUTTON IDM_FONT BUTTON IDM_BACKCOLOR END ///////////////////////////////////////////////////////////////////////////// // // Bitmap // ID_MYTOOLBAR BITMAP DISCARDABLE "mytoolba.bmp" MYBMP BITMAP DISCARDABLE "MYBMP.bmp" ///////////////////////////////////////////////////////////////////////////// // // Dialog // MYSUPPORT DIALOG DISCARDABLE 0, 0, 114, 134 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION CAPTION "サポート情報" FONT 14, "System" BEGIN DEFPUSHBUTTON "OK",IDOK,32,112,50,14 LTEXT "",IDC_STATIC2,32,101,71,8,SS_NOTIFY LTEXT "URL: ",IDC_STATIC,7,101,20,8 CONTROL "MYBMP",IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,7,7,98,82 END ///////////////////////////////////////////////////////////////////////////// // // Cursor // MYCURSOR CURSOR DISCARDABLE "mycursor.cur" ///////////////////////////////////////////////////////////////////////////// // // Icon // MYICON ICON DISCARDABLE "icon1.ico"

メニューに「ツールバーの外観」が増えました。右クリックメニューでも 表示されるようにしました。

// rich19.cpp ...省略... #define SZMYVERSION "猫でもわかるRTF#猫でもわかるRTF Ver0.19" ...省略... char szClassName[] = "rich19"; //ウィンドウクラス ...省略... int nToolType; //1:Old Type 2:Flat Type 3:透明 4:ツールバーのみ透明 ...省略...

バージョン番号を一応変えておきます。また、現在のツールバーのスタイル をグローバル変数に記憶させておきます。

WinMain, InitApp, InitInstance

の各関数に変更はありません。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { ...省略... static UINT uToolStyle; INITCOMMONCONTROLSEX iccex; switch (msg) { case WM_CREATE: iccex.dwSize = sizeof(INITCOMMONCONTROLSEX); iccex.dwICC = ICC_BAR_CLASSES; InitCommonControlsEx(&iccex); ...省略... case WM_COMMAND: ...省略... case IDM_OLD: uToolStyle = (UINT)GetWindowLong(hTool, GWL_STYLE); if (uToolStyle & TBSTYLE_FLAT) uToolStyle ^= TBSTYLE_FLAT; if (uToolStyle & TBSTYLE_TRANSPARENT) uToolStyle ^= TBSTYLE_TRANSPARENT; SetWindowLong(hTool, GWL_STYLE, (LONG)uToolStyle); InvalidateRect(hTool, NULL, TRUE); nToolType = 1; break; case IDM_FLAT: uToolStyle = (UINT)GetWindowLong(hTool, GWL_STYLE); if (uToolStyle & TBSTYLE_FLAT) uToolStyle ^= TBSTYLE_FLAT; if (uToolStyle & TBSTYLE_TRANSPARENT) uToolStyle ^= TBSTYLE_TRANSPARENT; uToolStyle |= TBSTYLE_FLAT; SetWindowLong(hTool, GWL_STYLE, (LONG)uToolStyle); InvalidateRect(hTool, NULL, TRUE); nToolType = 2; break; case IDM_TRANSPARENT: uToolStyle = (UINT)GetWindowLong(hTool, GWL_STYLE); if (uToolStyle & TBSTYLE_FLAT) uToolStyle ^= TBSTYLE_FLAT; if (uToolStyle & TBSTYLE_TRANSPARENT) uToolStyle ^= TBSTYLE_TRANSPARENT; uToolStyle |= (TBSTYLE_TRANSPARENT | TBSTYLE_FLAT); SetWindowLong(hTool, GWL_STYLE, (LONG)uToolStyle); InvalidateRect(hTool, NULL, TRUE); nToolType = 3; break; case IDM_TRANSPARENT2: uToolStyle = (UINT)GetWindowLong(hTool, GWL_STYLE); if (uToolStyle & TBSTYLE_FLAT) uToolStyle ^= TBSTYLE_FLAT; if (uToolStyle & TBSTYLE_TRANSPARENT) uToolStyle ^= TBSTYLE_TRANSPARENT; uToolStyle |= TBSTYLE_TRANSPARENT; SetWindowLong(hTool, GWL_STYLE, (LONG)uToolStyle); InvalidateRect(hTool, NULL, TRUE); nToolType = 4; break; ...省略...

InitCommonControlsExという当たらして関数を使ってみました。 従来のInitCommonControls関数でも差し支えはありません。(多分)

BOOL InitCommonControlsEx( LPINITCOMMONCONTROLSEX lpInitCtrls );

これで,コモンコントロールを初期化します。なお、InitCommonControls関数に ついては第57章を参照して下さい。

INITCOMMONCONTROLSEX構造体は次のように定義されています。

typedef struct tagINITCOMMONCONTROLSEX { DWORD dwSize; DWORD dwICC; } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;

dwSizeにはこの構造体のサイズを指定します。

dwICCには、dllから呼び出すコモンコントロールクラスを指定します。 ICC_BAR_CLASSは、ツールバー,ステータスバーなどを使用するとき指定します。 他にも山ほどありますのでヘルプで見ておいて下さい。

さて、WM_COMMANDのところのIDM_OLD, IDM_FLAT, IDM_TRANSPARENT, IDM_TRANSPARENT2のところは特に解説は不要ですね。

SetInitialFont, SetMyFont, SetCenter, SetLeft, SetRight, ClearCheck, RTF_Save, RTF_SaveAs, MySaveProc, RTF_Open, MyReadProc

の各関数に変更はありません。

void RTF_CheckMenu(HWND hEdit, HMENU hMenu) { ...省略... //ツールバーのスタイルを調べる switch (nToolType) { case 1://従来タイプ EnableMenuItem(hMenu, IDM_OLD, MF_GRAYED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_FLAT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT2, MF_ENABLED | MF_BYCOMMAND); break; case 2://フラットタイプ EnableMenuItem(hMenu, IDM_OLD, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_FLAT, MF_GRAYED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT2, MF_ENABLED | MF_BYCOMMAND); break; case 3://透明タイプ EnableMenuItem(hMenu, IDM_OLD, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_FLAT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT, MF_GRAYED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT2, MF_ENABLED | MF_BYCOMMAND); break; case 4: //ボタンのみ透明 EnableMenuItem(hMenu, IDM_OLD, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_FLAT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hMenu, IDM_TRANSPARENT2, MF_GRAYED | MF_BYCOMMAND); break; } return; }

グローバル変数のnToolTypeを見て,現在のツールバータイプを調べ そのメニュー項目をグレー表示にして使用不可能にしています。

RTF_Print, PrinterSet, GetPrintInfo, RTF_All, RTF_AddPageNo, RTF_SetWYSIWYG, RTF_New, RTF_Vertical, RTF_Horizontal, RTF_BackColor,

の各関数に変更はありません。

HWND MakeMyToolbar(HWND hWnd) { HWND hTool; HINSTANCE hInst; TBADDBITMAP tab; HBITMAP hBmp; int nIndex, i; UINT uToolType; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hTool = CreateToolbarEx(hWnd, WS_CHILD | WS_BORDER | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_ALTDRAG, ID_TOOLBAR, 9, (HINSTANCE)HINST_COMMCTRL, IDB_STD_SMALL_COLOR, tbBut, 9, 0, 0, 0, 0, sizeof(TBBUTTON)); hBmp = CreateMappedBitmap(hInst, ID_MYTOOLBAR, 0, NULL, 0); tab.hInst = NULL; tab.nID = (UINT)hBmp; nIndex = SendMessage(hTool, TB_ADDBITMAP, 7, (LPARAM)&tab); for (i = 0; i <= 6; i++) tbBmp[i].iBitmap += nIndex; SendMessage(hTool, TB_ADDBUTTONS, 7, (LPARAM)&tbBmp[0]); //初期状態でフラットツールバーに uToolType = (UINT)GetWindowLong(hTool, GWL_STYLE); uToolType |= (TBSTYLE_FLAT); SetWindowLong(hTool, GWL_STYLE, (LONG)uToolType); InvalidateRect(hTool, NULL, TRUE); nToolType = 2;//グローバル変数 return hTool; }

従来どおりにツールバーを作っておいてからフラットタイプにしています。

InsertSep, MakeMyStatusbar, SetStatusFontInfo, IsEditButtonAvailable, IsPasteButtonAvailable, SetStatusClock, RTF_SetTab, SetAlignmentButton, SetButtonHV, MyToolProc, RTF_Num, MakeMyRuler, MyStaticProc, MyEditProc, MyAboutProc, MyAboutStaticProc

の各関数に変更はありません。
[SDK第2部 Index] [総合Index] [Previous Chapter] [Next Chapter]

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