[WinAPI]Voorkomen dat common dialog IsDialogMessage aanroept

Pagina: 1
Acties:

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 20:47

Tomatoman

Fulltime prutser

Topicstarter
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:

Afbeeldingslocatie: http://img389.imageshack.us/img389/1561/dlg7mf.jpg

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.


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
Ik heb er geen verstand van hoor, maar kan je die 'IsDialogMessage' niet overriden en dan niet implementeren ? :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee dat kan niet.

Kun je WM_GETDLGCODE niet afvangen en, indien het bericht voor een van je delphi controls is, returnen dat je alle toetsen zelf af wilt handelen (DLGC_WANTALLKEYS), zodat die toetsmessages uiteindelijk toch bij de controls zelf terecht komen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 20:47

Tomatoman

Fulltime prutser

Topicstarter
.oisyn schreef op maandag 28 november 2005 @ 13:46:
Nee dat kan niet.

Kun je WM_GETDLGCODE niet afvangen en, indien het bericht voor een van je delphi controls is, returnen dat je alle toetsen zelf af wilt handelen (DLGC_WANTALLKEYS), zodat die toetsmessages uiteindelijk toch bij de controls zelf terecht komen?
Bij een wizard komt WM_GETDLGCODE niet binnen in de WindowProc en evenmin bij een Open dialog. Het kan zijn dat de berichten direct naar de betreffende controls worden gestuurd, maar daar heb ik niets aan, aangezien ik er dan geen invloed op heb. Bij een memo lijkt de tab ook niet aan te komen, maar de pijltjestoetsen en de entertoets wel. Van een memo wordt de WM_GETDLGCODE als volgt afgehandeld:
Delphi:
1
2
3
4
5
6
7
8
procedure TCustomMemo.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  inherited;
  if FWantTabs then Message.Result := Message.Result or DLGC_WANTTAB
  else Message.Result := Message.Result and not DLGC_WANTTAB;
  if not FWantReturns then
    Message.Result := Message.Result and not DLGC_WANTALLKEYS;
end;
of FWantTabs nou true of false is maakt geen verschil. Hieruit constateer ik dat IsDialogMessage zich niet altijd iets aantrekt van wat WM_GETDLGCODE als return value heeft.

Een goede grap mag vrienden kosten.