[WinAPI] TBBUTTON mit relativen Wert

Hunter

Erfahrenes Mitglied
Ich habe das Problem, dass meine Toolbar relativ ist/sein muss. Es scheitert jedoch beim TBBUTTON struct.
C++:
void addToolbar(HWND hWnd, const int nItems) {
     TBBUTTON tbb[nItems] = {
     //code
     };
}

Könnte mir jemand Tipps geben, oder wie man es umgehen kann? Oder sollte ich dynamisch Speicher zuweisen?
 
Mit "relativ" meinst du dynamisch, sprich eine variable Anzahl an Buttons?

Du kannst einen std::vector<TBBUTTON> verwenden, oder einen Pointer:

TBBUTTON* pButtons = new TBBUTTON[nItems];

delete[] pButtons nicht vergessen

Die TBBUTTON-Structs musst du nach dem TB_ADDBUTTON nicht mehr aufbewahren, d.h. du könntest es auch wie die MFC-Wrapper-Klasse CToolBar machen:

Die nimmt ein einzelnes TBBUTTON-Struct und setzt es in einer For-Schleife.
 
Jetzt hab ich doch noch ein Problem:
C++:
	//Initialisiere Button-Infos
	TBBUTTON *tbButtons = new TBBUTTON[nItems];

	for(int i = 0; i < nItems; i++) {
		tbButtons[i].iBitmap = i;
		tbButtons[i].idCommand = i+500;
		tbButtons[i].fsState = TBSTATE_ENABLED;
		tbButtons[i].fsStyle = buttonStyles;
		tbButtons[i].dwData = 0;
		tbButtons[i].iString = (INT_PTR) itemsString[i];
	}

Da hier keine Toolbar erstellt worden ist, habe ich natürlich im Debug-Mode nachgeforscht. GetLastError() gibt keine Fehlermeldung aus. Dann hab ich mal einen Haltepunkt in der Schleife gesetzt: siehe da, die Schleife wird "ignoriert". Sie wird aus irgendeinem Grund nicht ausgeführt. Die Schleife wird nur ausgeführt, wenn ich nItems durch einen Wert (zB: 5, 6) ersetze, jedoch wird selbst dort keine Toolbar erstellt.
Jemand eine Idee?
 
Zuletzt bearbeitet:
Das alleine befüllt ja nur das TBBUTTON-Array, zeig mal den Code, wie du den Toolbar erstellst und die Buttons einfügst.
 
C++:
HIMAGELIST hImageList = 0;
const DWORD buttonStyles = NULL;

	//Erstelle Window
	hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_WRAPABLE | TBSTYLE_LIST | CCS_NODIVIDER | CCS_NOPARENTALIGN,
								 2, 2, 230, 500, hWnd, NULL, (HINSTANCE) hImageList, NULL);

        //itemsString[] vorbereiten
        ...
        ...
       
        //ImageList erstellen
	hImageList = ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, quantityFiles, 0);
        //Schleife zum hinzufügen mit ImageList_AddIcon()
        ...
	//Set Imagelist
    SendMessage(hWndToolbar, TB_SETIMAGELIST, ImageListID, (LPARAM) hImageList);

	//Lade Button-Images
    SendMessage(hWndToolbar, TB_LOADIMAGES, IDB_STD_LARGE_COLOR, (LPARAM) HINST_COMMCTRL);


	//Initialisiere Button-Infos
	TBBUTTON *tbButtons = new TBBUTTON[quantityFiles];
	//ZeroMemory(&tbButtons, sizeof(tbButtons));
	for(int i = 0; i < quantityFiles; i++) {
		tbButtons[i].iBitmap	= i;
		tbButtons[i].idCommand	= i+1000;
		tbButtons[i].fsState	= TBSTATE_ENABLED;
		tbButtons[i].fsStyle	= buttonStyles;
		tbButtons[i].dwData		= 0;
		tbButtons[i].iString	= (INT_PTR) itemsString[i];
	}

	//Add Buttons
	SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), NULL);
    SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM) (const int) (sizeof(tbButtons)/20), (LPARAM) &tbButtons);
	SendMessage(hWndToolbar, TB_SETBUTTONSIZE, NULL, MAKELPARAM(230, 32));				//Set size

	//Größe ändern und anzeigen
	SendMessage(hWndToolbar, TB_AUTOSIZE, NULL, NULL); 
    ShowWindow(hWndToolbar,  TRUE);	


	//Speicher wieder freigeben
	delete[] itemsString;	
	delete[] tbButtons;

Hoffe der Code ist einigermaßen leserlich.
 
Hallo Hunter

C:
sizeof(tbButtons)

-> sizeof(TBUTTON*) = 4 (x86) bzw 8 (x64)

Man nehme mit:
Der moderne Programmierer verwendet keine C-Arrays (haben keine Vorteile, ausschliesslich Nachteile) und verwendet i.d.R. auch nie explizit new und delete sondern hat dafür die entsprechenden Wrapper.

stattverwende
T*std::shared_ptr<T>, std::unique_ptr<T>, std::weak_ptr<T>
T[N]std::array<T, N>, std::vector<T>(N)


Viele Grüsse
Cromon
 
Zuletzt bearbeitet:
...verwendet i.d.R. auch nie explizit new und delete sondern hat dafür die entsprechenden Wrapper

Sorry, aber das ist mir zu pauschalisiert. Wie willst du dynamisch Objekte erzeugen ohne new? Polymorphismus ist ohne ge-new-te Objekte kaum machbar (Referenzen eignen sich nicht so gut zum herumtragen). Wo kommt das Objekt her, das im shared_ptr steckt?

Was Cromon sagen wollte:

mach aus sizeof( tbButtons ) ein sizeof( TBBUTTON ) * quantityFiles
 
Zuletzt bearbeitet:
Sorry, aber das ist mir zu pauschalisiert. Wie willst du dynamisch Objekte erzeugen ohne new? Polymorphismus ist ohne ge-new-te Objekte kaum machbar (Referenzen eignen sich nicht so gut zum herumtragen). Wo kommt das Objekt her, das im shared_ptr steckt?

C++:
void bar(const std::shared_ptr<Bar>& barPtr) {
}

std::shared_ptr<Foo> foo = std::make_shared<Foo>();
bar(foo);
 
Vielen Dank an euch zwei für die Hilfe. Der Fehler lag beim Hinzufügen der Buttons (TB_ADDBUTTONS)

C++:
    SendMessage(hWndToolbar, TB_ADDBUTTONS, sizeof(TBBUTTON*), (LPARAM) tbButtons);
Da tbButtons ja schon ein Pointer ist, war das & überflüssig.
 
Zurück