2014-09-15 12 views
5

Ich versuche, das Verhalten einer Windows-Symbolleiste zu verstehen - insbesondere, wie die folgenden Werte in Wechselwirkung treten:Windows-Werkzeugleiste - Controlling Knopfgröße und Polsterung

  • die Größe des Bitmap-Bildes verwendet
  • die effektiven Größe eines Symbolschaltfläche
  • die Polsterung zwischen dem Bild und der Knopf Kante
  • die Höhe der Werkzeugleiste

Der mit einem Button angezeigte Text ist in meinem Fall nicht relevant.

Was ich eigentlich tun möchte, ist eine Option für den Benutzer, so dass er aus mehreren Symbolleistenschaltflächen Größen auswählen kann (Bitmaps von sagen, 16x16, 32x32 oder 48x48 Pixel) und die Symbolleiste entsprechend der Option wieder anzeigen Wert ändert sich. Dies wird implementiert, indem die Bildlisten der Symbolleiste zerstört und mit den entsprechenden Bitmaps neu erstellt werden. Das Problem, das ich momentan habe, ist, dass beim Umschalten von Größe 16 auf 48 und zurück auf Größe 16 die Werkzeugleiste etwas anders aussieht als zuvor.

Dies ist, was die Symbolleiste aussieht, wenn die Anwendung gestartet wird (richtig):

Before switching the toolbar size

Sobald ich wechseln Größe 48 und wieder zurück, es sieht aus wie diese (falsche):

After switching to a larger size and back

Alle Schaltflächen sind höher als zuvor und jede Dropdown-Schaltfläche hat zusätzlichen Platz um die Bitmap und den Dropdown-Pfeil.

(Zu Testzwecken wurde die Symbolleiste so hoch eingestellt, dass alle Schaltflächengrößen ohne Erhöhung der Höhe angepasst werden können. Damit soll ausgeschlossen werden, dass die Änderung der Schaltflächengröße auf einer möglichen Änderung der Symbolleiste beruht vorübergehend Größe Schalt 48)

Es sieht aus, als ob eine zusätzliche Polsterung zwischen einer Schaltfläche Bitmap und die Schaltfläche Rand wiedergegeben wurden - als ob die Symbolleiste mit größeren Bitmaps Wiederaufbau Tasten/Windows-verursacht intern die Polsterung erhöhen (was machen würde Sinn, aber nicht verringern, wenn ich später die Symbolleiste mit den kleineren Bitmaps/Schaltflächen neu erstellen. Das Senden von TB_GETPADDING gibt jedoch immer 0x00060007 zurück, das anzeigt, dass das Standard (richtige) Auffüllen für 16 x 16 Bitmaps vorhanden ist.

In einem Versuch, das Problem zu lösen, indem ich Padding selbst einstellen, habe ich den Stil TBSTYLE_AUTOSIZE auf alle Nicht-Trenner-Schaltflächen eingestellt (dies ist erforderlich, um Padding anzuwenden). Mit diesem Stil, ohne auch nur TB_SETPADDING Aufruf, nach 48 bis Größe Vermittlungs- und wieder zurück, sieht die Symbolleiste wie folgt aus:

After switching to a larger size and back, with TBSTYLE_AUTOSIZE

In diesem Fall wird die Schaltfläche Höhe auch falsch ist.

Die Frage ist: Was die Tasten verursacht unterschiedlich angezeigt werden, nachdem die Bildlisten Wiederaufbau?

Einige beiseite Hinweise:

  • Wenn die Symbolleiste Gebäude, nenne ich TB_SETBITMAPSIZE, aber weder TB_SETBUTTONSIZE noch TB_SETPADDING, weil die Bitmap-Größe alles, was ich habe, und ich davon ausgegangen, würde die Knopfgröße aus, dass korrekt abgeleitet werden .
  • Ich bin mir bewusst, ich könnte einfach das gesamte Toolbar-Fenster von Grund auf neu erstellen (nicht nur die Bildlisten), aber das möchte ich vermeiden, so dass ich mit dem gleichen Werkzeugleistenfenster arbeiten kann.
  • Ich kenne den Symbolleistenstil CCS_NORESIZE (es ist derzeit festgelegt) und die Nachricht TB_AUTOSIZE, aber Experimente mit ihnen haben zu keinen Erkenntnissen geführt.
+0

Hallo, welche Sprache benutzen Sie? –

+0

Steve: Ich benutze C++. – Dabbler

Antwort

2

Ich kann nicht sagen, was das Problem ist (es gibt keinen Code in der Frage), aber es ist am wahrscheinlichsten , dass die Lösung der Zerstörung der Liste der Bilder dies verursacht. Sie müssen die Listen nicht zerstören, sondern die Schaltflächen entfernen und neue hinzufügen. Der Balg Code funktioniert gut:

erstellen ToolBar:

if((toolBarHwnd = CreateWindowEx(
       0, 
       TOOLBARCLASSNAME,, 
       NULL, 
       WS_VISIBLE | WS_CHILD | TBSTYLE_WRAPABLE, 
       0, 
       0, //820, 
       0, 
       0, 
       winHwnd, //main window 
       (HMENU)IDC_TOOLBAR, 
       hThisInstance, 
       NULL 
      )) == NULL){/*Error*/} 

erstellen Abbildungsliste des für Ihre Bilder:

HIMAGELIST g_hImageListSmall = NULL, g_hImageListMedium = NULL, g_hImageListLarge = NULL; 
int numButtons = 3 
g_hImageListSmall = ImageList_Create(16, 16, // Dimensions of individual bitmaps. 
           ILC_COLOR16 | ILC_MASK, // Ensures transparent background. 
           numButtons, 0); 
g_hImageListMedium = ImageList_Create(32, 32, 
           ILC_COLOR16 | ILC_MASK, 
           numButtons, 0); 
g_hImageListLarge = ImageList_Create(48, 48, 
           ILC_COLOR16 | ILC_MASK, 
           numButtons, 0); 

Bilder hinzufügen, um die Listen:

HBITMAP hBitmapImageSmall = NULL, hBitmapImageMedium = NULL, hBitmapImageLarge = NULL; 
hBitmapImageSmall = LoadImage(NULL, L"....YourBitmap.bmp", IMAGE_BITMAP, 16, 16, 0x10); 
ImageList_Add(g_hImageListSmall , hBitmapImageSmall, NULL); 
ImageList_Add(g_hImageListSmall , hBitmapImageSmall, NULL); 
ImageList_Add(g_hImageListSmall , hBitmapImageSmall, NULL); //I am using the same image 

hBitmapImageMedium = LoadImage(NULL, L"....YourBitmap.bmp", IMAGE_BITMAP, 32, 32, 0x10); 
ImageList_Add(g_hImageListSmall , hBitmapImageMedium , NULL); 
ImageList_Add(g_hImageListSmall , hBitmapImageMedium , NULL); 
ImageList_Add(g_hImageListSmall , hBitmapImageMedium , NULL); 

Das gleiche wi th der Großen (48x48)

g_hImageListSmall zum ToolBar für Start hinzufügen:

//Set the image list. 
SendMessage(toolBarHwnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)g_hImageListSmall); 

// Initialize button info. 
// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants. 
TBBUTTON tbButtons[numButtons] = 
{ 
    { 0, IDM_NEW, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL }, 
    { 1, IDM_OPEN, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL}, 
    { 2, IDM_SAVE, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL} 
}; 

// Add buttons. 
SendMessage(toolBarHwnd, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); 
SendMessage(toolBarHwnd, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons); 

// Resize the toolbar 
SendMessage(toolBarHwnd, TB_AUTOSIZE, 0, 0); 

Das ist der erste Schritt.

schreiben zwei Funktionen:

Wann immer Sie die Größe der Tasten in ToolBar ändern wollen:

RemoveButtons(); 
AddButtons(LARGE); //or SMALL, MEDIUM 

Referenzen:

How to Create Toolbars
How to Customize Toolbars

4

Die allgemeinen Steuerelemente waren eine wichtige Bug Factory in Windows. Microsoft hatte große Probleme damit, sie über 6 wichtige Windows-Versionen und 10 Versionen von comctl32.dll kompatibel zu halten. Besonders die visuellen Renderer waren ein Problempunkt.

Kernproblem ist, dass die API für sie vor 18 Jahren in Stein gemeißelt wurde, ohne einen vernünftigen Weg, um es anders arbeiten zu lassen, als es in ihrer ersten Veröffentlichung funktionierte. Ihr Code hat sehr viele Appcompat-Hacks hinzugewonnen, um dies zu erreichen. Ein solcher Hack wird beispielsweise einen Wert behandeln, der von der vorherigen Version zurückgegeben wurde, so dass das Client-Programm keine Ahnung hat und nicht wissen muss, dass es mit einer anderen Version als der, gegen die es getestet wurde, arbeitet.

Dies hat Nebenwirkungen, die Sie entdecken werden, wenn Sie die Steuerelemente auf eine ungewöhnliche Weise verwenden, die sich sehr von der Art unterscheidet, wie sie normalerweise von Windows-Programmen für Fleisch und Kartoffeln verwendet werden. Genau wie dein Szenario. Sehr hohe Chancen, dass Sie mit dem internen Status der Symbolleiste kämpfen, den Sie nicht sehen können und der nicht richtig wiederhergestellt wird, wenn Sie die Größe wechseln. Ganz undenkbar, dieser innere Zustand ist überhaupt nicht sichtbar. Anders als von den unerwünschten Nebenwirkungen.

Die Lösung ist die, die Sie bereits kennen. Erstellen Sie die Symbolleiste von Grund auf neu. So kann es nicht schief gehen.

+1

Ich hatte meine Kopfschmerzen aufgrund dieser Kontrollen. Ganz zu schweigen von einigen DLL Hell, die nur zum Spaß in die Quere kommen. –