如何在winapi编程中使用工具栏的自定义图标

时间:2014-02-13 00:44:17

标签: c++ image winapi toolbar

我正在尝试使用自己的自定义图像在win32 winapi程序中创建工具栏。这就是我所拥有的(在我的WM_CREATE情况下):

#define IDT_MAIN_TOOL     101
TBBUTTON tbb[ 1 ];
TBADDBITMAP tbab;

HWND hToolbar = CreateWindowEx( 0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT, 0, 0, 0, 0, hwnd, ( HMENU )IDT_MAIN_TOL, NULL, NULL );

SendMessage( hToolbar, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 );

tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_HIST_LARGE_COLOR;
SendMessage( hToolbar, TB_ADDBITMAP, 0, ( LPARAM )&tbab );

ZeroMemory( tbb, sizeof( tbb ) );

tbb[ 0 ].iBitmap = HIST_BACK;
// I've also tried tbb[ 0 ].iBitmap = LoadIcon( NULL, "browse_back.ico" );
// However, iBitmap must be an integer and can't figure out how to use my 'browse_back.ico' image
tbb[ 0 ].fsState = TBSTATE_ENABLED;

SendMessage( hToolbar, TB_ADDBUTTONS, sizeof( tbb ) / sizeof( TBBUTTON ), ( LPARAM )&tbb );

我想使用自己的图标图片:'browse_back.ico'作为该工具栏按钮的图像。这是如何完成的?不确定这是否有必要,但我使用的是Microsoft Visual C ++ 2010 Express。

2 个答案:

答案 0 :(得分:3)

Read the documentation

  

iBitmap   键入:int

     

按钮图像的从零开始的索引。将此成员设置为I_IMAGECALLBACK,工具栏将发送TBN_GETDISPINFO通知代码以在需要时检索图像索引。

     

版本5.81。将此成员设置为I_IMAGENONE以指示该按钮没有图像。按钮布局不包含位图的任何空间,只包含文本。

     

如果按钮是分隔符,也就是说,如果fsStyle设置为BTNS_SEP,则iBitmap确定分隔符的宽度(以像素为单位)。 有关从图像列表中选择按钮图像的信息,请参阅TB_SETIMAGELIST消息。

因此,您需要使用ImageList_Create()创建图像列表,使用ImageList_Add()ImageList_ReplaceIcon()将ICO图像添加到其中,使用TB_SETIMAGELIST将其与工具栏相关联,然后你可以将tbb[0].iBitmap设置为图像列表中的ICO索引。

答案 1 :(得分:0)

我知道有两种方法。一个正在使用TBADDBITMAP,另一个正在使用HIMAGELIST。在此示例中,我使用TBADDBITMAP,但我个人更喜欢HIMAGELIST

project.rc

#include "resource.h"

IDB_DOCUMENT         BITMAP   "document.bmp"
IDB_DRUGS            BITMAP   "drugs.bmp"

resource.h

#define IDTB_TOOLBAR         1000
#define IDB_DOCUMENT         1001
#define IDB_DRUGS            1002

#define ID_ADD_NEW           2000

tb.c

#include <windows.h>
#include <commctrl.h>
#include "resource.h"

const char ClassName[] = "ToolbarExample";

HWND hWndToolBar;
HINSTANCE g_hInstance;

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
   switch (Msg)
   {
      case WM_CREATE:
      {
         TBADDBITMAP tbab1, tbab2;
         TBBUTTON    tbb[2]; 

         hWndToolBar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd,
               (HMENU)IDTB_TOOLBAR, g_hInstance, NULL);

         if (!hWndToolBar)
         {
            MessageBox(NULL, "ToolBar Failed.", "Error", MB_OK | MB_ICONERROR);
            return 0;
         }

         SendMessage(hWndToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
         
         SendMessage(hWndToolBar, TB_SETBITMAPSIZE, (WPARAM)0, (LPARAM)MAKELONG(32, 32));

         // Add Bitmaps
         tbab1.hInst  = g_hInstance;
         tbab1.nID    = IDB_DOCUMENT; 
         SendMessage(hWndToolBar, TB_ADDBITMAP, (WPARAM) 1, (LPARAM) &tbab1);

         tbab2.hInst  = g_hInstance;
         tbab2.nID    = IDB_DRUGS;
         SendMessage(hWndToolBar, TB_ADDBITMAP, (WPARAM) 1, (LPARAM) &tbab2);


         // Add Buttons
         ZeroMemory(tbb, sizeof(tbb));

         tbb[0].iBitmap    = 0; // The index of the bitmap on toolbar bitmap collection
         tbb[0].idCommand  = ID_ADD_NEW; 
         tbb[0].fsState    = TBSTATE_ENABLED; 
         tbb[0].fsStyle    = TBSTYLE_BUTTON; 
         tbb[0].iString    = SendMessage(hWndToolBar, TB_ADDSTRING, 0, (LPARAM)TEXT("Add New"));

         tbb[1].iBitmap    = 1; 
         tbb[1].idCommand  = 0;
         tbb[1].fsState    = TBSTATE_ENABLED; 
         tbb[1].fsStyle    = TBSTYLE_BUTTON; 
         tbb[1].iString    = SendMessage(hWndToolBar, TB_ADDSTRING, 0, (LPARAM)TEXT("Drugs"));

         SendMessage(hWndToolBar, TB_ADDBUTTONS, sizeof(tbb) / sizeof(TBBUTTON), (LPARAM)&tbb);
      }
      break; 

   case WM_COMMAND:
   {
      switch(LOWORD(wParam))
      {
         case ID_ADD_NEW:
         {
            MessageBox(NULL, "Toolbar Button One", "Success", MB_OK | MB_ICONINFORMATION);
         }
         break; 
      }
      return 0;
   } 
   break; 

   case WM_SIZE:
      SendMessage(hWndToolBar, TB_AUTOSIZE, 0, 0);
   break;
   
   case WM_CLOSE:
      DestroyWindow(hWnd);
   break;

   case WM_DESTROY:
      PostQuitMessage(0);
   break;

   default:
      return (DefWindowProc(hWnd, Msg, wParam, lParam));

   }

   return 0;
}

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
   InitCommonControls();

   g_hInstance = hInstance;

   WNDCLASS            wc;
   wc.style            = 0;
   wc.lpfnWndProc      = (WNDPROC)WndProc;
   wc.cbClsExtra       = 0;
   wc.cbWndExtra       = 0;
   wc.hInstance        = hInstance;
   wc.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
   wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
   wc.lpszMenuName     = NULL;
   wc.lpszClassName    = ClassName;

   if (!RegisterClass(&wc))
   {
      MessageBox(NULL, "Failed To Register The Window Class.", "Error", MB_OK | MB_ICONERROR);
      return 0;
   }

   HWND    hWnd;
   hWnd = CreateWindow(ClassName, "Toolbars", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      MessageBox(NULL, "Window Creation Failed.", "Error", MB_OK | MB_ICONERROR);
      return 0;
   }

   ShowWindow(hWnd, SW_SHOW);
   UpdateWindow(hWnd);
   MSG    Msg;
   
   while (GetMessage(&Msg, NULL, 0, 0))
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }
   return Msg.wParam;
}