Libérer la taille maximale d'une fenêtre par subclassing

Description

Suite à une question sur le fofo (En gros, comment avoir une fenêtre firefox dont la taille maximum n'est pas limitée à la résolution de l'écran) :
http://www.delphifr.com/forum/sujet-SIMULER-ECRAN-PLUS-GRAND-RESOLUTION-MAX-SON-MONITEUR_1473380.aspx#6

Windows ne limite en fait pas à proprement parler la taille des fenêtres à la résolution de l'écran. Il ne fait que proposer ce comportement par défaut aux applications qui ont tout à fait le droit de le surcharger en traitant le message WM_GETMINMAXINFO.
http://msdn.microsoft.com/en-us/library/ms632626(VS.85).aspx

Les développeurs Delphi connaissent bien ce message très utile pour limiter le redimensionnement de la fenêtre :
"http://www.delphicorner.f9.co.uk/articles/wapi8.htm"

Dans le cas de la question, c'est un peu plus compliqué car c'est le comportement d'une autre application que l'on souhaite modifier.

Pour modifier le comportement d'une fenêtre d'un processus différent du sien, la méthode la plus classique est le subclassing.

Un hook avec SetWindowHookEx est moins approprié.
Déjà car WH_GETMESSAGE n'intercepte que les messages postés, pas les messages sendés (Ce qui est le cas de WM_GETMINMAXINFO).
En effet, les messages sendés (SendMessage) appellent directement la procédure de la fenêtre, tandis que les messages postés (PostMessage) sont récupérer par Peek/GetMessage (-> WH_GETMESSAGE).
Quant aux hook WH_CALLWNDPROC/WH_CALLWNDPROCRET, d'après la documentation, il ne permettent pas de modifier les messages.
Ce serait curieux que le système fasse une copie de MINMAXINFO pour appeler le hook, mais je n'ai pas vérifier. Autant faire ça proprement via un subclassing.

On peut trouver de la doc sur le subclassing ici :
http://msdn.microsoft.com/en-us/library/ms633570(VS.85).aspx#subclassing_window

Mais dans cet exemple il est appliqué dans le cas où l'application modifie une de ses propres fenêtres.
Le problème est que l'on passe à SetWindowLong l'adresse d'une fonction qui doit se trouver dans l'autre processus.
Donc pour pouvoir utiliser le subclassing dans un autre processus, il faut lui injecter une dll.

Mon source propose donc un .exe et une dll, sous forme d'un groupe de projet UpdateWindowMaxSize.bpg :
1/ UpdateWindowMaxSize.dpr : Le .exe injecteur qui permet de sélectionner une fenêtre et injecter la dll.
2/ WindowSubClassing : La dll qui va réaliser le subclassing.

Remarques :
La dll fait un subclassing sur toutes les fenêtres principales actuellement ouverte du processus (Pas uniquement la fenêtre sélectionnée).
Elle ne libère pas la taille des fenêtres de taille fixe (Devrait être faisable avec SetWindowLong de GWL_EXSTYLE/GWL_STYLE pour modifier le style).
Essayer d'injecter deux fois le même processus n'a aucun effet : la dll n'est chargé qu'une fois par Windows.
Le .exe est dispo en .exec dans le zip, a renommé si quelqu'un veut essayer sans avoir Delphi.

Une fois la taille libéré, on peut agrandir la fenêtre jusqu'à 30000 pixels (Théorie) en jouant un peu avec.
Un SetWindowPos peut être ajouté au code de la dll pour agrandir la fenêtre automatiquement.

Conclusion :


Le subclassing ne se limite bien sûr pas à la taille des fenêtre et est une méthode très utile quand il faut modifier une application tierce, ce qui est toujours compliqué.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.