In mijn applicaties pas ik soms een common dialog aan, zoals het standaard Windows 'Open File' dialoogvenster. Dat werkt allemaal best aardig, maar ik loop telkens tegen hetzelfde probleem aan. Iedere modal dialog roept bij het gebruik van navigatietoetsen zoals Tab, Shift+Tab en de pijltjestoetsen IsModalDialog aan. Dat gebeurt automatisch, nog voordat de WindowProc woordt aangeroepen. Het probleem: hierdoor wordt de tabvolgorde van mijn componenten verpest.
Wat gebeurt er?
Ik laat mijn applicatie een paar controls in het dialoogvenster toevoegen, zoals de group box met de twee check boxen in het plaatje hieronder:

Zoals gezegd handelt het dialoogvenster alle navigatietoetsen af, zonder dat de appliatie daar iets mee te maken heeft. Als je de tab-toets gebruikt, ga je via Bestandsnaam naar Bestandstypen, Openen en Annuleren naar de twee check boxen. Aan de hand van de Z-order van beide check boxen wordt door IsDialogMessage de tabvolgorde bepaald. 'Open as read-only' wordt door mijn applicatie gecreëerd voordat 'Open exclusively' wordt gecreëerd, zodat 'Open as read-only' lager in de Z-order staat. Nu werkt IsModalDialog zodanig dat je met de navigatietoetsen eerst naar de control gaat die het hoogst staat in de Z-order en daarna de Z-order afgaat tot de control met de laagste Z-order. De laatst gecreëerde control heeft echter de hoogste Z-order. Als je de tabtoets gebruikt, ga je daarom van 'Annuleren' eerst naar 'Open exclusively' en pas daarna naar 'Open as read-only'. Kortom: de volgorde van alle controls is precies omgekeerd.
Wat is het probleem?
De Z-order valt achteraf wel te herstellen met functies zoals BringToFront(), maar daarmee ben ik er niet. Als programmeertaal gebruik ik Delphi en daarin kun je zelf de tabvolgorde aangeven. De tabvolgorde is daarbij onafhankelijk van de Z-order, maar is in eerste instantie precies omgekeerd aan de Z-order. Alle Delphi controls hebben zelf de functionaliteit aan boord om de navigatietoetsen af te handelen. Dat het dialoogvenster automatisch IsDialogMessage aanroept is daarom niet alleen overbodig, maar zelfs zeer ongewenst, omdat de tabvolgorde een puinhoop wordt.
Wat wil ik bereiken?
Ik wil dat het dialoogvenster IsDialogMessage niet meer aanroept, maar de keyboard messages gewoon doorgeeft aan mijn controls. Maar hoe?
Meer info over hoe dialoogvensters met navigatietoetsen omgaan staat in de Platform SDK onder Dialog Box Programming Considerations in de paragraaf 'Dialog Box Keyboard Interface'.
Wat gebeurt er?
Ik laat mijn applicatie een paar controls in het dialoogvenster toevoegen, zoals de group box met de twee check boxen in het plaatje hieronder:

Zoals gezegd handelt het dialoogvenster alle navigatietoetsen af, zonder dat de appliatie daar iets mee te maken heeft. Als je de tab-toets gebruikt, ga je via Bestandsnaam naar Bestandstypen, Openen en Annuleren naar de twee check boxen. Aan de hand van de Z-order van beide check boxen wordt door IsDialogMessage de tabvolgorde bepaald. 'Open as read-only' wordt door mijn applicatie gecreëerd voordat 'Open exclusively' wordt gecreëerd, zodat 'Open as read-only' lager in de Z-order staat. Nu werkt IsModalDialog zodanig dat je met de navigatietoetsen eerst naar de control gaat die het hoogst staat in de Z-order en daarna de Z-order afgaat tot de control met de laagste Z-order. De laatst gecreëerde control heeft echter de hoogste Z-order. Als je de tabtoets gebruikt, ga je daarom van 'Annuleren' eerst naar 'Open exclusively' en pas daarna naar 'Open as read-only'. Kortom: de volgorde van alle controls is precies omgekeerd.
Wat is het probleem?
De Z-order valt achteraf wel te herstellen met functies zoals BringToFront(), maar daarmee ben ik er niet. Als programmeertaal gebruik ik Delphi en daarin kun je zelf de tabvolgorde aangeven. De tabvolgorde is daarbij onafhankelijk van de Z-order, maar is in eerste instantie precies omgekeerd aan de Z-order. Alle Delphi controls hebben zelf de functionaliteit aan boord om de navigatietoetsen af te handelen. Dat het dialoogvenster automatisch IsDialogMessage aanroept is daarom niet alleen overbodig, maar zelfs zeer ongewenst, omdat de tabvolgorde een puinhoop wordt.
Wat wil ik bereiken?
Ik wil dat het dialoogvenster IsDialogMessage niet meer aanroept, maar de keyboard messages gewoon doorgeeft aan mijn controls. Maar hoe?
Meer info over hoe dialoogvensters met navigatietoetsen omgaan staat in de Platform SDK onder Dialog Box Programming Considerations in de paragraaf 'Dialog Box Keyboard Interface'.
[ Voor 3% gewijzigd door Tomatoman op 27-11-2005 23:35 ]
Een goede grap mag vrienden kosten.