De quelles fenêtres parle t-on ?
ou
Corrections et synthèse des articles antérieurs
Correction
Dans l’un de mes derniers articles « Dessiner un
rectangle de sélection » Gregory Adams m’a fait remarquer que j’avais oublié
de libérer le contexte de périphérique. C’est une faute grave que j’ai corrigée
depuis. Mais cette faute je l’avais reproduite dans « Définir une
sélection avec un rectangle de sélection », dans un « Un séparateur
sympathique » et même dans la nouvelle version proposée du browser. J’ai
modifié mes articles en conséquence, mais certains garderons peut-être ce bug.
C’est la première raison qui me fait publier à nouveau ces différents codes.
Mais il y a une raison plus profonde.
GetDC versus GetWindowDC
La deuxième raison concerne le commentaire de Frédéric
Steczycki qui m’a fait remarquer que GetDC était beaucoup plus simple à
utiliser que GetWindowDC surtout quand il s’agit de dessiner dans la partie
cliente de la fenêtre. Ma première réaction a été « Mais c’est bien sur !
Pourquoi n’y ai-je pas pensé plus tôt ? ».
Sur ce, je modifie mon premier code « Dessiner un
rectangle de sélection », je remplace les GetWindowDC par des GetDC plus
simple. Ca marche, c’est impeccable.
Je passe au deuxième programme « Définir une sélection
avec un rectangle de sélection », c’est impeccable. Et puis c’est beaucoup
plus élégant.
J’arrive au troisième programme « Un séparateur
sympathique ». Là, c’est pas sympa du tout car ça ne marche plus. Le
rectangle de sélection ne se dessine pas. Je compare mon ancien code au
nouveau, la seule chose importante qui change, c’est GetDC à la place de
GetWindowDC. J’y passe finalement une bonne partie d’un WE pour m’apercevoir
que j’avais, dans cet exemple, une fenêtre top-level (contrairement aux deux
premiers exemples). Je constate alors qu’en mettant ShowWindow = 0 dans la
définition de la form ça marche, alors qu’avec ShowWindow=2 (top-level) ça ne
marche pas. Bon ! je me dis que si je ne dessine rien c’est que
probablement je ne suis pas dans le bon contexte de périphérique. Je me penche
sur la doc (et oui…) et je tombe sur 3 fonctions sys que je ne connaissais
pas :
SYS(2325) Returns
the hWnd of a client window from the parent window's WHANDLE.
SYS(2326) Returns
a Visual FoxPro WHANDLE from a window’s hWnd.
SYS(2327) Returns
a window's hWnd from a Visual FoxPro window’s WHANDLE.
(Je fais remarquer au passage que la doc pour 2325 est
fausse. Cette fonction retourne une WHANDLE et non pas une hWnd).
En fait on a le schéma suivant :
Form frm
|
|
Windows handle
|
|
VFP window handle
|
Window’s
Form
|
|
hw = frm.HWnd
|
==>
|
hf = sys(
2326, m.hw )
|
Client window
(Same window if standard different if top
level)
|
Top-level
|
hwc=sys(2327,m.hfc)
|
<==
|
hfc = sys( 2325, m.hf ) et
hfc <> hf
|
Standard
|
<==
|
hfc = sys( 2325, m.hf ) et hfc==hf
|
Donc à la place de :
(1) hDC = GetDC( thisform.HWnd )
J’essaye :
(2) hDC = GetDC( Sys(2327,Sys( 2325, Sys(2326,
thisform.HWnd))))
Fantastique! Ca marche.
C’est clair, il faut passer par les handles VFP pour
atteindre la fenêtre cliente dans le cas des top-level. Mais quand on est en
fenêtre normale, (1) et (2) donnent le même résultat. Donc, en prenant la
formule (2) ça marche dans tous les cas. Je suis super content, mes trois
premiers programmes marchent maintenant sur le même principe.
Je m’attaque alors au browser, je passe à GetDC, avec la
formule (2). Et là encore, grosse déception, ça ne marche pas on ne voit plus
le splitter. La principale différence maintenant, est qu’on a des objets
descendants de OleControl.
Je refais donc profil bas, et je reprends mon tout premier
programme tout simple en ajoutant un OleControl au milieu de la fenêtre. Et
bien je constate qu’on n’arrive pas à dessiner au dessus des OleControls.
Moralité : pour dessiner un splitter au dessus de tout
il faut absolument dessiner dans la fenêtre principale de la form en prenant le
contexte de périphérique de la form avec GetWindowDC et non pas avec GetDC.
J’ai finalement découvert cela par erreur. Tient ! Cela
me rappelle quelque chose.
C'est bien Robert.
Une toute, toute petite remarque ...
Je vois qui tu m'a fait cadeau de la lettre S en ecrivant mon nom. (AdamS)
Ce n'est pas grave, cela arrive
Et quand cela arrive, je la prefere en postfix - comme tu as fait, plutot qu'en prefix ;)