Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De meeste Windows-toepassingen gebruiken werkbalkbesturingselementen om gebruikers handige toegang te bieden tot de programmafunctionaliteit. Statische werkbalken hebben echter een aantal tekortkomingen, zoals te weinig ruimte om alle beschikbare hulpprogramma's effectief weer te geven. De oplossing voor dit probleem is om de werkbalken van uw toepassing door de gebruiker aan te passen. Vervolgens kunnen gebruikers ervoor kiezen om alleen de hulpmiddelen weer te geven die ze nodig hebben en ze kunnen ze ordenen op een manier die past bij hun persoonlijke werkstijl.
Notitie
Werkbalken in dialoogvensters kunnen niet worden aangepast.
Als u aanpassingen wilt inschakelen, neemt u de CCS_ADJUSTABLE algemene stijl-vlag voor besturingselementen op wanneer u het besturingselement voor de werkbalk maakt. Er zijn twee basismethoden voor aanpassing:
- Het dialoogvenster Aanpassing. Dit door het systeem geleverde dialoogvenster is de eenvoudigste benadering. Het biedt gebruikers een grafische gebruikersinterface waarmee ze pictogrammen kunnen toevoegen, verwijderen of verplaatsen.
- Tools voor slepen en neerzetten. Door slepen en neerzetten te implementeren, kunnen gebruikers hulpprogramma's naar een andere locatie op de werkbalk verplaatsen of verwijderen door ze van de werkbalk te slepen. Het biedt gebruikers een snelle en eenvoudige manier om hun werkbalk te organiseren, maar staat hen niet toe om hulpprogramma's toe te voegen.
U kunt een benadering of beide implementeren, afhankelijk van de behoeften van de toepassing. Geen van deze twee benaderingen voor aanpassing biedt een ingebouwd mechanisme, zoals een knop Annuleren of Ongedaan maken, om de werkbalk terug te keren naar de voormalige staat. U moet de api voor werkbalkbesturingselementen expliciet gebruiken om de status van de precustomisatie van de werkbalk op te slaan. Indien nodig kunt u deze opgeslagen informatie later gebruiken om de werkbalk terug te zetten naar de oorspronkelijke staat.
Wat u moet weten
Technologieën
Voorwaarden
- C/C++
- Programmeren van Windows-gebruikersinterface
Aanwijzingen
Dialoogvenster Aanpassen
Het dialoogvenster Aanpassen wordt geleverd door het werkbalkbesturingselement om gebruikers een eenvoudige manier te bieden om hulpmiddelen toe te voegen, te verplaatsen of te verwijderen. Gebruikers kunnen het starten door te dubbelklikken op de werkbalk. Toepassingen kunnen het aanpassingsdialoogvenster programmatisch starten door het besturingselement voor de werkbalk een TB_CUSTOMIZE bericht te verzenden.
In de volgende afbeelding ziet u een voorbeeld van het dialoogvenster voor het aanpassen van de werkbalk.
De hulpmiddelen in de keuzelijst aan de rechterkant zijn de hulpmiddelen die zich momenteel op de werkbalk bevinden. In eerste instantie bevat deze lijst de hulpprogramma's die u opgeeft wanneer u de werkbalk maakt. De keuzelijst aan de linkerkant bevat de hulpprogramma's die beschikbaar zijn om aan de werkbalk toe te voegen. Uw toepassing is verantwoordelijk voor het invullen van die lijst (met uitzondering van het scheidingsteken, dat automatisch wordt weergegeven).
De werkbalk meldt dat uw toepassing een aanpassingsdialoogvenster opent door het bovenliggende venster een TBN_BEGINADJUST meldingscode te verzenden, gevolgd door een TBN_INITCUSTOMIZE meldingscode. In de meeste gevallen hoeft de toepassing niet te reageren op deze meldingscodes. Als u echter niet wilt dat het dialoogvenster Werkbalk aanpassen een Help-knop weergeeft, kunt u TBN_INITCUSTOMIZE afhandelen door TBNRF_HIDEHELP te retourneren.
Het besturingselement voor de werkbalk verzamelt vervolgens de informatie die nodig is om het dialoogvenster te initialiseren door drie reeks meldingscodes te verzenden, in de volgende volgorde:
- Een TBN_QUERYINSERT meldingscode voor elke knop op de werkbalk om te bepalen waar knoppen kunnen worden ingevoegd. Retourneer false om te voorkomen dat een knop direct links van de in het meldingsbericht opgegeven knop wordt ingevoegd. Als u FALSE retourneert voor alle TBN_QUERYINSERT meldingscodes, wordt het dialoogvenster niet weergegeven.
- Een TBN_QUERYDELETE meldingscode voor elk hulpprogramma dat zich momenteel op de werkbalk bevindt. Retourneer TRUE als een hulpprogramma kan worden verwijderd of FALSE als dat niet het geval is.
- Een reeks TBN_GETBUTTONINFO meldingscodes om de lijst met beschikbare knoppen te vullen. Als u een knop wilt toevoegen aan de lijst, vult u de NMTOOLBAR structuur in die wordt doorgegeven met de meldingscode en retourneert u TRUE-. Als u geen gereedschappen meer hebt om toe te voegen, keer dan terug ONWAAR. Houd er rekening mee dat u informatie kunt retourneren voor knoppen die al op de werkbalk staan; deze knoppen worden niet toegevoegd aan de lijst.
Het dialoogvenster wordt vervolgens weergegeven en de gebruiker kan beginnen met het aanpassen van de werkbalk.
Wanneer het dialoogvenster is geopend, kan uw toepassing verschillende meldingscodes ontvangen, afhankelijk van de acties van de gebruiker:
- TBN_QUERYINSERT. De gebruiker heeft de locatie van een hulpprogramma op de werkbalk gewijzigd of een hulpprogramma toegevoegd. Retourneer FALSE om te voorkomen dat de tool op die locatie wordt ingevoegd.
- TBN_DELETINGBUTTON. De gebruiker staat op het punt om een hulpprogramma uit de werkbalk te verwijderen.
- TBN_CUSTHELP. De gebruiker heeft op de knop Help geklikt.
- TBN_TOOLBARCHANGE. De gebruiker heeft een hulpprogramma toegevoegd, verplaatst of verwijderd.
- TBN_RESET. De gebruiker heeft op de knop Opnieuw instellen geklikt.
Nadat het dialoogvenster is vernietigd, ontvangt uw toepassing een TBN_ENDADJUST meldingscode.
In het volgende codevoorbeeld ziet u een manier om werkbalkaanpassing te implementeren.
// The buttons are stored in an array of TBBUTTON structures.
//
// Constants such as STD_FILENEW are identifiers for the
// built-in bitmaps that have already been assigned as the toolbar's
// image list.
//
// Constants such as IDM_NEW are application-defined command identifiers.
TBBUTTON allButtons[] =
{
{ MAKELONG(STD_FILENEW, ImageListID), IDM_NEW, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"New" },
{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Open"},
{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Save"},
{ MAKELONG(STD_CUT, ImageListID), IDM_CUT, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Cut" },
{ MAKELONG(STD_COPY, ImageListID), IDM_COPY, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Copy"},
{ MAKELONG(STD_PASTE, ImageListID), IDM_PASTE, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Paste"}
};
// The following appears in the window's message handler.
case WM_NOTIFY:
{
switch (((LPNMHDR)lParam)->code)
{
case TBN_GETBUTTONINFO:
{
LPTBNOTIFY lpTbNotify = (LPTBNOTIFY)lParam;
// Pass the next button from the array. There is no need to filter out buttons
// that are already used—they will be ignored.
int buttonCount = sizeof(allButtons) / sizeof(TBBUTTON);
if (lpTbNotify->iItem < buttonCount)
{
lpTbNotify->tbButton = allButtons[lpTbNotify->iItem];
return TRUE;
}
else
{
return FALSE; // No more buttons.
}
}
break;
case TBN_QUERYINSERT:
case TBN_QUERYDELETE:
return TRUE;
}
}
Hulpmiddelen voor slepen en neerzetten
Gebruikers kunnen de knoppen op een werkbalk ook opnieuw rangschikken door op shift te drukken en de knop naar een andere locatie te slepen. Het slepen-en-neerzetten-proces wordt automatisch afgehandeld door de toolbar. Er wordt een spookafbeelding van de knop weergegeven terwijl deze wordt gesleept en de werkbalk opnieuw rangschikt nadat deze is verwijderd. Gebruikers kunnen op deze manier geen knoppen toevoegen, maar ze kunnen een knop verwijderen door deze van de werkbalk te verwijderen.
Hoewel het besturingselement van de werkbalk deze bewerking normaal gesproken automatisch doet, worden ook twee meldingscodes voor uw toepassing verzonden: TBN_QUERYDELETE en TBN_QUERYINSERT. Als u het proces voor slepen en neerzetten wilt beheren, moet u deze meldingscodes als volgt afhandelen:
- De TBN_QUERYDELETE meldingscode wordt verzonden zodra de gebruiker de knop probeert te verplaatsen, voordat de ghost-knop wordt weergegeven. Geef FALSE om te voorkomen dat de knop wordt verplaatst. Als u TRUEretourneert, kan de gebruiker het hulpprogramma verplaatsen of verwijderen door het uit de werkbalk te verwijderen. Als een hulpprogramma kan worden verplaatst, kan het worden verwijderd. Als de gebruiker echter een hulpprogramma verwijdert, verzendt het besturingselement op de werkbalk uw toepassing een TBN_DELETINGBUTTON meldingscode. Op dat moment kunt u ervoor kiezen om de knop opnieuw in te voegen op de oorspronkelijke locatie, waardoor de verwijdering wordt geannuleerd.
- De TBN_QUERYINSERT meldingscode wordt verzonden wanneer de gebruiker de knop op de werkbalk probeert te verwijderen. Als u wilt voorkomen dat de knop die wordt verplaatst links van de in de melding opgegeven knop wordt neergezet, moet u ONWAARretourneren. Deze meldingscode wordt niet verzonden als de gebruiker het hulpprogramma van de werkbalk verwijdert.
Als de gebruiker een knop probeert te slepen zonder ook op de Shift-toets te drukken, verwerkt het besturingselement op de werkbalk de bewerking slepen en neerzetten niet. Uw toepassing ontvangt echter een TBN_BEGINDRAG meldingscode om het begin van een sleepbewerking aan te geven en een TBN_ENDDRAG meldingscode om het einde aan te geven. Als u deze vorm van slepen en neerzetten wilt inschakelen, moet uw toepassing deze meldingscodes afhandelen, de benodigde gebruikersinterface opgeven en de werkbalk aanpassen om wijzigingen weer te geven.
Werkbalken opslaan en herstellen
Tijdens het aanpassen van een werkbalk moet uw toepassing mogelijk gegevens opslaan, zodat u de werkbalk in de oorspronkelijke staat kunt herstellen. Om te starten met het opslaan of herstellen van de status van een werkbalk, stuurt u een TB_SAVERESTORE bericht met de wParam ingesteld op TRUE. De wParam waarde van dit bericht geeft aan of u een opslag- of herstelbewerking aanvraagt. Nadat het bericht is verzonden, zijn er twee manieren om de bewerking opslaan/herstellen te verwerken:
- Met algemene besturingselementen versie 4.72 en eerder moet u een TBN_GETBUTTONINFO handler implementeren. Het besturingselement van de werkbalk verzendt deze meldingscode om informatie over elke knop aan te vragen terwijl deze wordt hersteld.
- Versie 5.80 bevat een optie voor opslaan/herstellen. Aan het begin van het proces en wanneer elke knop wordt opgeslagen of hersteld, ontvangt uw toepassing een meldingscode voor TBN_SAVE of TBN_RESTORE. Als u deze optie wilt gebruiken, moet u meldingshandlers implementeren om de bitmap- en statusgegevens op te geven die nodig zijn om de status van de werkbalk op te slaan of te herstellen.
Werkbalkstatussen worden opgeslagen in een gegevensstroom die bestaat uit afwisselend blokken van door Shell gedefinieerde gegevens en blokken met toepassingsgedefinieerde gegevens. Voor elke knop wordt één gegevensblok van elk type opgeslagen, samen met een optioneel blok met globale gegevens dat toepassingen aan het begin van de stream kunnen plaatsen. Tijdens het opslaan voegt de TBN_SAVE-handler de toepassingsgedefinieerde blokken toe aan de gegevensstroom. Tijdens het herstelproces leest de TBN_RESTORE handler elk blok en geeft de Shell de informatie die nodig is om de werkbalk te reconstrueren.
Hoe een TBN_SAVE-melding te verwerken
De eerste TBN_SAVE meldingscode wordt verzonden aan het begin van het opslagproces. Voordat knoppen worden opgeslagen, worden de leden van de NMTBSAVE structuur ingesteld, zoals wordt weergegeven in de volgende tabel.
| Lid | Instelling |
|---|---|
| iItem | –1 |
| cbData | De hoeveelheid geheugen die nodig is voor door Shell gedefinieerde gegevens. |
| cButtons | Het aantal knoppen. |
| pData- | De berekende hoeveelheid geheugen die nodig is voor door de toepassing gedefinieerde gegevens. Normaal gesproken neemt u enkele algemene gegevens op, plus gegevens voor elke knop. Voeg die waarde toe aan cbData- en wijs voldoende geheugen toe aan pData- om alles vast te houden. |
| Huidige | De eerste ongebruikte byte in de gegevensstroom. Als u geen algemene werkbalkgegevens nodig hebt, stelt u pCurrent = pData- in, zodat deze verwijst naar het begin van de gegevensstroom. Als u algemene werkbalkgegevens nodig hebt, slaat u deze op pData-op en stelt u pCurrent- in op het begin van het ongebruikte gedeelte van de gegevensstroom voordat u terugkeert. |
Als u algemene werkbalkgegevens wilt toevoegen, plaatst u deze aan het begin van de gegevensstroom. Ga met pCurrent naar het einde van de globale gegevens, zodat deze naar het begin van het ongebruikte gedeelte van de gegevensstroom wijst, en keer terug.
Nadat u terugkeert, begint de Shell met het opslaan van knopgegevens. Hiermee worden de door Shell gedefinieerde gegevens toegevoegd voor de eerste knop op pCurrent, waarna pCurrent naar het begin van het ongebruikte gedeelte wordt verplaatst.
Nadat elke knop is opgeslagen, wordt er een TBN_SAVE-meldingscode verzonden en wordt NMTBSAVE met de volgende leden geretourneerd.
| Lid | Instelling |
|---|---|
| iItem | De op nul gebaseerde index van het knopnummer. |
| pCurrent | Een aanwijzer naar de eerste ongebruikte byte in de gegevensstroom. Als u aanvullende informatie over de knop wilt opslaan, slaat u deze op de locatie op waarnaar wordt verwezen door pCurrent en werkt u pCurrent- bij om hierna naar het eerste ongebruikte gedeelte van de gegevensstroom te verwijzen. |
| TBBUTTON | Een TBBUTTON structuur die de knop beschrijft die wordt opgeslagen. |
Wanneer u de meldingscode ontvangt, moet u eventuele knopspecifieke informatie extraheren die u nodig hebt uit TBBUTTON-. Wanneer u een knop toevoegt, kunt u de dwData lid van de structuur TBBUTTON gebruiken om specifieke gegevens voor de toepassing op te slaan. Laad uw gegevens in de gegevensstroom op pCurrent. Ga met pCurrent naar het einde van uw gegevens, wijs opnieuw naar het begin van het ongebruikte gedeelte van de stream en keer terug.
De Shell gaat vervolgens naar de volgende knop, voegt de gegevens toe aan pData, gaat verder met pCurrent, laadt TBBUTTON, en verzendt nog een TBN_SAVE meldingscode. Dit proces wordt voortgezet totdat alle knoppen zijn opgeslagen.
Opgeslagen werkbalken herstellen
Het herstelproces keert simpel gezegd het bewaarproces om. Aan het begin ontvangt uw toepassing een TBN_RESTORE meldingscode met de iItem lid van de NMTBRESTORE structuur ingesteld op –1. De cbData lid wordt ingesteld op de grootte van pData, en cButtons wordt ingesteld op het aantal knoppen.
De notificatiehandler moet de algemene informatie extraheren die aan het begin van pData is geplaatst tijdens het opslaan, en pCurrent te verplaatsen naar het begin van het eerste blok met Shell-gedefinieerde gegevens. Stel cBytesPerRecord in op de grootte van de gegevensblokken die u hebt gebruikt om de knopgegevens op te slaan. Stel cButtons in op het aantal knoppen en ga terug.
De volgende NMTBRESTORE is voor de eerste knop. De pCurrent lid wijst naar het begin van uw eerste set knopgegevens, en iItem wordt ingesteld op de knopindex. Pak die gegevens uit en ga pCurrent. Laad de gegevens in TBBUTTON-en retourneer. Als u een knop van de herstelde werkbalk wilt weglaten, stelt u de idCommand in lid van TBBUTTON- in op nul. De Shell herhaalt het proces voor de resterende knoppen. Naast de NMTBSAVE en NMTBRESTORE berichten, kunt u ook berichten zoals TBN_RESET gebruiken om een werkbalk op te slaan en te herstellen.
In het volgende codevoorbeeld wordt een werkbalk opgeslagen voordat deze wordt aangepast en hersteld als de toepassing een TBN_RESET bericht ontvangt.
int i;
LPNMHDR lpnmhdr;
static int nResetCount;
static LPTBBUTTON lpSaveButtons;
LPARAM lParam;
switch( lpnmhdr->code)
{
case TBN_BEGINADJUST: // Begin customizing the toolbar.
{
LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
// Allocate memory for the button information.
nResetCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
lpSaveButtons = (LPTBBUTTON)GlobalAlloc(GPTR, sizeof(TBBUTTON) * nResetCount);
// In case the user presses reset, save the current configuration
// so the original toolbar can be restored.
for(i = 0; i < nResetCount; i++)
{
SendMessage(lpTB->hdr.hwndFrom,
TB_GETBUTTON, i,
(LPARAM)(lpSaveButtons + i));
}
}
return TRUE;
case TBN_RESET:
{
LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
int nCount, i;
// Remove all of the existing buttons, starting with the last one.
nCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
for(i = nCount - 1; i >= 0; i--)
{
SendMessage(lpTB->hdr.hwndFrom, TB_DELETEBUTTON, i, 0);
}
SendMessage(lpTB->hdr.hwndFrom, // Restore the saved buttons.
TB_ADDBUTTONS,
(WPARAM)nResetCount,
(LPARAM)lpSaveButtons);
}
return TRUE;
case TBN_ENDADJUST: // Free up the memory you allocated.
GlobalFree((HGLOBAL)lpSaveButtons);
return TRUE;
}
Verwante onderwerpen