begin process at 2010 02 10 00:15:22
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > FENETRE NON RECTANGULAIRE (WIN32)

FENETRE NON RECTANGULAIRE (WIN32)


 Information sur la source

Note :
7,8 / 10 - par 5 personnes
7,80 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Niveau :Débutant Date de création :24/02/2005 Date de mise à jour :07/03/2005 22:51:21 Vu / téléchargé :7 130 / 904

Auteur : Urgo

Ecrire un message privé
Site perso
Commentaire sur cette source (21)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Façon la plus simple de créer une fenêtre non rectangulaire à l'aide d'un bmp et de la transparence.
Le prog tourne uniquement sur windows 2000 ou supérieur! C'est testé au lancement (merci BruNews).
Touche Echap pour quitter.
Codé en C/WIN32, compilé sous VS.NET 2003, testé sous XP.

Source

  • #define _WIN32_WINNT 0x0500
  • #include <windows.h>
  • #include "resource.h"
  • HBITMAP hBmp = 0;
  • HINSTANCE hInst = 0;
  • SIZE SizeBmp = {128, 128};
  • char szAppName[] = "BmpPerso";
  • LRESULT CALLBACK AppWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  • {
  • switch(uMsg) {
  • case WM_CREATE:
  • hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BMP));
  • SetLayeredWindowAttributes(hWnd, RGB(255, 0, 255), 0, LWA_COLORKEY);
  • return 0;
  • case WM_ERASEBKGND: {
  • HDC hDC, hMemDC;
  • HBITMAP hOldBmp;
  • hDC = (HDC)wParam;
  • if(hBmp) {
  • hMemDC = CreateCompatibleDC(hDC);
  • hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
  • BitBlt(hDC, 0, 0, SizeBmp.cx, SizeBmp.cy, hMemDC, 0, 0, SRCCOPY);
  • SelectObject(hMemDC, hOldBmp);
  • DeleteDC(hMemDC);
  • }
  • }
  • return 1;
  • case WM_NCHITTEST:
  • return HTCAPTION;
  • case WM_KEYDOWN:
  • if(wParam == VK_ESCAPE) PostMessage(hWnd, WM_CLOSE, 0, 0);
  • return 0;
  • case WM_DESTROY:
  • DeleteObject(hBmp);
  • PostQuitMessage(0);
  • return 0;
  • }
  • return DefWindowProc(hWnd, uMsg, wParam, lParam);
  • }
  • int InitInstance()
  • {
  • WNDCLASSEX wclsx;
  • wclsx.cbSize = sizeof(WNDCLASSEX);
  • wclsx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  • wclsx.lpfnWndProc = AppWndProc;
  • wclsx.cbClsExtra = 0;
  • wclsx.cbWndExtra = 0;
  • wclsx.hInstance = hInst;
  • wclsx.hIcon = 0;
  • wclsx.hCursor = LoadCursor(NULL, IDC_ARROW);
  • wclsx.hbrBackground = 0;
  • wclsx.lpszMenuName = 0;
  • wclsx.lpszClassName = szAppName;
  • wclsx.hIconSm = 0;
  • return RegisterClassEx(&wclsx);
  • }
  • DWORD VerifWin2KMini()
  • {
  • OSVERSIONINFO osvi;
  • osvi.dwPlatformId = osvi.dwMajorVersion = 0;
  • osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  • GetVersionEx(&osvi);
  • if(osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) return 0;
  • return (osvi.dwMajorVersion >= 5);
  • }
  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
  • {
  • MSG msg;
  • if(!VerifWin2KMini()) return 0;
  • hInst = hInstance;
  • if(!InitInstance()) return 0;
  • HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, szAppName,
  • WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS,
  • CW_USEDEFAULT, CW_USEDEFAULT, SizeBmp.cx, SizeBmp.cy,
  • 0, 0, hInst, 0);
  • ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd);
  • while(GetMessage(&msg, NULL, 0, 0)) {
  • TranslateMessage(&msg);
  • DispatchMessage(&msg);
  • }
  • return msg.wParam;
  • }
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include "resource.h"

HBITMAP hBmp = 0;
HINSTANCE hInst = 0;
SIZE SizeBmp = {128, 128};
char szAppName[] = "BmpPerso";

LRESULT CALLBACK AppWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
		case WM_CREATE:
			hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BMP));
			SetLayeredWindowAttributes(hWnd, RGB(255, 0, 255), 0, LWA_COLORKEY);
			return 0;
		case WM_ERASEBKGND: {
			HDC hDC, hMemDC;
			HBITMAP hOldBmp;
			hDC = (HDC)wParam;
			if(hBmp) {
				hMemDC = CreateCompatibleDC(hDC);
				hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
				BitBlt(hDC, 0, 0, SizeBmp.cx, SizeBmp.cy, hMemDC, 0, 0, SRCCOPY);
				SelectObject(hMemDC, hOldBmp);
				DeleteDC(hMemDC); 
			}
	      }
			return 1;
		case WM_NCHITTEST:
			return HTCAPTION;
		case WM_KEYDOWN:
			if(wParam == VK_ESCAPE) PostMessage(hWnd, WM_CLOSE, 0, 0);
			return 0;
		case WM_DESTROY:
			DeleteObject(hBmp);
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int InitInstance()
{
	WNDCLASSEX wclsx;
	wclsx.cbSize        = sizeof(WNDCLASSEX);
	wclsx.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wclsx.lpfnWndProc   = AppWndProc;
	wclsx.cbClsExtra    = 0;
	wclsx.cbWndExtra    = 0;
	wclsx.hInstance     = hInst;
	wclsx.hIcon         = 0;
	wclsx.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wclsx.hbrBackground = 0;
	wclsx.lpszMenuName  = 0;
	wclsx.lpszClassName = szAppName;
	wclsx.hIconSm       = 0; 
	return RegisterClassEx(&wclsx);
}

DWORD VerifWin2KMini()
{
	OSVERSIONINFO osvi;
	osvi.dwPlatformId = osvi.dwMajorVersion = 0;
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osvi);
	if(osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) return 0;
	return (osvi.dwMajorVersion >= 5);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
{
	MSG msg;
	if(!VerifWin2KMini()) return 0;
	hInst = hInstance;
	if(!InitInstance()) return 0;
	HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, szAppName, 
										WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS,
										CW_USEDEFAULT, CW_USEDEFAULT, SizeBmp.cx, SizeBmp.cy,
										0, 0, hInst, 0);
	ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd);
	while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

27 février 2005 16:30:18 :
- Modification mineure grâce au commentaire de Boing (merci à lui).
07 mars 2005 22:51:21 :
- Dernière mise à jour (voir le commentaire de Boing pour les détails).

 Sources du même auteur

Source avec Zip Source avec une capture BITMAP EN GRAYSCALE (WIN32)
Source avec Zip Source avec une capture MINI SPY (WIN32)
Source avec Zip CONVERTIR IMAGES & WAV VERS FICHIER AVI (WIN32)

 Sources de la même categorie

Source avec Zip Source avec une capture CALENDRIER (WIN64) par BruNews
Source avec Zip Source avec une capture IMPRESSION EN WIN32 API AVEC OPTIONS par racpp
Source avec Zip Source avec une capture INFOTIP SHELL EXTENSION (BULLE DE L'EXPLORATEUR WINDOWS) (WI... par racpp
Source avec Zip Source avec une capture BROUILLAGE DES FICHIERS JAVASCRIPT ET CSS(WIN32) par gagah1
Source avec Zip Source avec une capture CHANGE CURSEUR par ganjarasta

Commentaires et avis

Commentaire de Boing le 25/02/2005 09:14:24

Hello,

Tu devrais plutôt afficher ton Bitmap en réponse à WM_ERASEBKGND comme ça tu évites plus tard des réaffichages intempestifs car WM_PAINT est appelé pour toutes les invalidations et WM_ERASEBKGND uniquement lorsqu'on invalide avec erase = TRUE.

Pour faire la "même" chose à peu prés et que cela fonctionne en plus sous 98 on utilise la fonction SetWindowRgn. On calcul la région du bitmap de fond et on restreint la fenêtre à cette région. Par contre, avec SetWindowRgn, on ne gère pas les transparences partielles.

Benoît

Commentaire de minet03 le 25/02/2005 18:20:38

ah quel dommage !!! c'est un code si intéressant, le seul problème c'est que tu ne commente rien dedans !!! c'est très dommage. Si tu pouvais juste rajouter des commentaire sur les ligne les plus importante, et pourquoi pas expliqué à quoi servent les fonctions (surtout la troisième, celle après l'enregistrement de la classe). 6/10

Commentaire de Urgo le 25/02/2005 18:55:14

C'est pourtant clair :

DWORD VerifWin2KMini()  // Vérifie si l'OS est W2K minimum (cf description de la source), l'appli ne démarrera pas si tu as Windows 98 par exemple.
Pk cette fonction? Tout simplement à cause de l'API SetLayeredWindowAttribute (pour la transparence) => VOIR MSDN

#define _WIN32_WINNT 0x0500 // Instruction qui indique que l'on utilise W2K ou supérieur, permet une compilation sans erreur => VOIR MSDN pour précisions

SIZE SizeBmp = {128, 128}; // Largeur puis hauteur du bmp utilisé

Voir http://www.cppfrance.com/code.aspx?ID=10721 pour comparer le nombre de lignes de code; moi je ne tourne plus sur Windows 98 depuis un bon moment!

Ici je ne suis pas obligé de traiter le message WM_ERASEBKGND, car le membre hbrBackground de la structure WNDCLASSEX est passé à zéro lors de la création de la classe de la fenêtre.

Bye
Urgo

Commentaire de minet03 le 25/02/2005 20:28:53

ok merci (mais c'est sans doute l'expression W2K que je ne comprend pas). Cela dit ces commentaire seront bien mieux dans le code.

Commentaire de Urgo le 25/02/2005 21:03:33

1Ko = 1024 octets
W2K = Windows 2000

Faut lire la description de la source avant de se ruer sur le code...

Va faire un tour sur http://msdn.microsoft.com si tu ne connais pas, tu y trouveras ton bonheur...

Télécharge JR4 et CP5 (si c'est pas déjà fait), ici :
http://brunews.free.fr/brunews/index.htm
(site de notre cher admin CS (Codes-Sources, pas le FPS non de dieu! :p) : le fabuleux BruNews)

Bye
Urgo

Commentaire de Boing le 26/02/2005 13:54:06

Hello Urgo,

C justement parceque tu mets hbrBackground à 0 (ou NULL) que tu devrais faire ton affichage du bitmap de fond de la fenêtre dans WM_ERASEBKGND...
C pas obligatoire, c'est juste plus optimisé.

Quand au support de Windows 98... Ca dépend de l'utilisateur visé. Je suis d'accord avec toi, si tu ne vises pas 98 le code que tu proproses est mieux. D'ailleurs je t'ai mis 8/10 pour la simplicité et la clareté de l'exemple.

a+
Benoît

Commentaire de Urgo le 26/02/2005 14:45:04

Ok, cette fois-ci j'ai compris. Merci à toi!

Le code sera mis à jour d'ici demain.

Bye
Urgo

Commentaire de yoyo269 le 06/03/2005 10:36:06

Bravo Urgo,

très bonne source.
Moi je dis ça vaut bien un 8/10.

YOYO, @+.

Commentaire de Boing le 07/03/2005 09:46:11

Hello Urgo,

Juste un petite remarque supplémentaire, Lorsque tu utilises SelectObject, tu dois sauvegarder le Handle de l'objet précédent et le rétablir une fois que tu as fini. De cette façon, GDI est capable de faire le nettoyage.

donc :
HBITMAP OldBmp = NULL;
hMemDC = CreateCompatibleDC(hDC);
OldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
BitBlt(hDC, 0, 0, SizeBmp.cx, SizeBmp.cy, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, OldBmp);
DeleteDC(hMemDC);

Le gros problème, c'est que le debugger intégré à Visual ne gère pas les ressources et GDI donc on ne sait jamais ce qui se passe vraiment sauf à regarder les ressources de l'OS qui diminuent... Ou alors il faut utiliser un autre debugger.

Petite astuce aussi :
Tu interceptes WM_LBUTTONDOWN et tu le transfères sur WM_NCLBUTTONDOWN, tu peux utiliser WM_NCHITTEST et renvoyer HTCAPTION. C'est pratique, tu peux renvoyer la valeur que tu veux, HTCLOSE pour une zone de fermeture,  HTNOWHERE pour une zone non cliquable...

A+
Benoît

Commentaire de Urgo le 07/03/2005 23:01:25

Source mise à jour (sans doute la dernière).
Je te remerci Benoît pour ton aide!

Ciao
Christian

Commentaire de _Jonathan le 10/03/2005 15:41:23

J'utilise devc++, et apparement LWA_COLORKEY n'est pas déclaré...
J'ai cherché dans windows.h et winuser.h mais je ne l'ai pas trouvé.
Meme sur msdn, j'ai trouvé un exemple, mais pas le code de LWA_COLORKEY...
Je pourré savoir le nombre que cette constante défini? ^^

merci!

Commentaire de _Jonathan le 10/03/2005 15:53:47

Un autre probleme :
SetLayeredWindowAttributes n'est pas déclarée non plus...
Quelqu'un pourait m'aider?

Commentaire de yoyo269 le 10/03/2005 17:19:37

Pour Jonathan :

#define LWA_COLORKEY    0x01

et

SLWA_FUNC MySetLayeredWindowAttributes;
HMODULE hUser32 = GetModuleHandle("USER32.DLL");
if (!hUser32) return false;
MySetLayeredWindowAttributes = (SLWA_FUNC)GetProcAddress(hUser32, "SetLayeredWindowAttributes");

J'espère que ça te servira.

YOYO, @+.

Commentaire de _Jonathan le 10/03/2005 18:30:37

oui, merci, tout marche maintenant, j'ai trouvé une source qui l'expliquai ^^

merci, a+

Commentaire de pixelinf le 09/08/2005 22:41:15

Petit probleme sur le programme, il ne prend plus en compte les messages, par exemple pour le traitement de la touche espace :

case WM_KEYDOWN:
            if(wParam == VK_ESCAPE) PostMessage(hWnd, WM_CLOSE, 0, 0);
            return 0;

ça ne marche pas, est ce que vous avez rencontré le même problème ou je suis le seul ? merci d'avance.

Commentaire de Urgo le 14/08/2005 18:14:51

OUI, tu es "le seul" (Da Only One) à avoir ce problème, merci de finir cette conversation par mp (si besoin est) afin d'éviter toute pollution avec des commentaires HS.

Commentaire de pixelinf le 14/08/2005 20:56:51

tu es susceptible on dirait, je n'ai pas critiqué ce que tu as fait, mais c'est juste chez moi il y a un problème, enfin bref!
En attendant, tu aurais dû t'abstenir de mettre ce genre de "commentaire".
Tu as le droit de fermer ta bouche mec ok :)

Bonne soirée

Commentaire de Urgo le 14/08/2005 23:10:53

Gros malin, j'ai été tout à fait correct dans ma réponse, excepté le fait que je ne t'ai pas vouvoyer, mais vu que tu n'as pas voulu donner ton âge je me suis accordé cette liberté.
Et puis ce genre de commentaire "ça marche pas", ça m'avance vachement...
Ca te fait ça uniquement avec mon exe, ou aussi lorsque tu compiles? Tu travailles sous dev, sous vs....?
Oui effectivement je suis direct dans mes propos et ça dérange, mais si tu n'es pas content tu peux toujours aller voir ailleurs, rien ne t'en empêche.

Je n'ai jamais refuser d'aider qqun lorsque cela était dans mes capacités.

Commentaire de pixelinf le 14/08/2005 23:25:33

Salut, Urgo repartons du bon pied ok, j'ai 21 ans voilà pour info :).

Donc enfait, je sais pas si ça vient de moi, mais desfois il ne prend pas en compte le fait que j'appuis sur echap, je suis sous devcpp, c'est pas ton exe qui marche pas, c'est quand je je prend ton code et je compile, il faut peut être faire une manip particuliere pour la compile ou direct ? De plus quand je met l'image dans le fichier ressource ça marche pas, il n'affiche pas la fenêtre, je susi obligé de charger une image de l'extérieure, tu sais c'est dû à quoi ?

(Cependant ton code est super c'est ce que je cherchais).

Merci d'avance.


Commentaire de Urgo le 15/08/2005 00:10:42

J'en ai aucune idée, faudrais que tu vois ça avec un utilisateur de dev-cpp...
Dans cette source j'utilise LoadBitmap(..), y'a rien de mystique si tu connais le Win32.

Ciao

Commentaire de Ombitious_Developper le 10/12/2006 13:06:19

Salut:

Très bonne source. (8/10)

Juste une question: Comment ajouter des boutons sans pourtant gâcher l'images utiliser comme fond?

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,515 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales