Fenêtre flottante sans focus (win32 api)

Description

Je profite d'une question sur le forum pour déposer ce petit code source montrant comment créer une fenêtre pour la mettre au premier plan mais sans qu'elle puisse prendre le focus. Il est possible d'utiliser aussi une boite de dialogue. Même en cliquant dessus, la fenêtre en cours d'utilisation garde le focus. Tout repose sur l'utilisation des styles étendus WS_EX_NOACTIVATE et WS_EX_TOPMOST. Le style WS_EX_TOOLWINDOW est également utilisé pour empêcher la fenêtre d'apparaitre dans la barre des tâches. Pour illuster le bon fonctionnement de la fenêtre, quatre boutons permettent d'émettre différents sons. Ce genre de fenêtre peut être utilisé pour faire une boite à outils toujours visible, accessible et ne capturant pas le focus des autres fenêtres. Il est à noter qu'elle est déplaçable juste en la glissant là où on veut.
Ce petit projet a été réalisé sous Visual C/C++ 2005 et très facilement adaptable.
Pour tester l'exécutable renommez le en SansFocus.exe
J'espère que ce sera utile.

Source / Exemple :


#define _WIN32_WINNT 0x0500 // Windows 2000 et supérieur
#include <windows.h>

LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	// Déclaration des HWNDs en static:
	static HWND hBeep,hSon1,hSon2,hSon3,hFermer;
	switch(message)
	{
	case WM_CREATE:
		{
			// Création des contrôles:
			CreateWindowEx(0,"button",0,WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,4,4,276,140,hwnd,0,0,0);
			hBeep=CreateWindowEx(0,"button","Beep",WS_CHILD | WS_VISIBLE ,20,20,100,20,hwnd,0,0,0);
			hSon1=CreateWindowEx(0,"button","Son 1",WS_CHILD | WS_VISIBLE,20,50,100,20,hwnd,0,0,0);
			hSon2=CreateWindowEx(0,"button","Son 2",WS_CHILD | WS_VISIBLE,20,80,100,20,hwnd,0,0,0);
			hSon3=CreateWindowEx(0,"button","Son 3",WS_CHILD | WS_VISIBLE,20,110,100,20,hwnd,0,0,0);
			hFermer=CreateWindowEx(0,"button","Fermer",WS_CHILD | WS_VISIBLE,160,70,100,20,hwnd,0,0,0);
			// Changement de la police des contrôles:
			HFONT font=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
			HWND child=0;
			while(child=FindWindowEx(hwnd,child,0,0))SendMessage(child,WM_SETFONT,(WPARAM)font,0);
			return 0;
		}

	case WM_LBUTTONDOWN:
		// Permettre le déplacement de notre fenêtre sans barre de titre:
		return DefWindowProc(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);

	case WM_MOVING:
	case WM_SIZING:
		{
			// Forcer le déplacement ou le redimensionnement de la fenêtre pour contourner un bug:
			RECT *pRect = (RECT *)lParam;
			SetWindowPos(hwnd, 0, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, 0);
			return TRUE;
		}

	case WM_CLOSE:
		// Détruire la fenêtre:
		DestroyWindow(hwnd);
		return 0;

	case WM_DESTROY:
		// Forcer la sortie de la boucle des messages:
		PostQuitMessage(0);
		return 0;

	case WM_COMMAND:
		// Clic sur les boutons des sons:
		if((HWND)lParam==hBeep) Beep(800,50);
		if((HWND)lParam==hSon1) MessageBeep(MB_OK);
		if((HWND)lParam==hSon2) MessageBeep(MB_ICONHAND);
		if((HWND)lParam==hSon3) MessageBeep(MB_ICONEXCLAMATION);
		// Clic sur le bouton Fermer:
		if((HWND)lParam==hFermer)SendMessage(hwnd,WM_CLOSE,0,0);
		return 0;

	default:
		break;
	}
	// Appeler la procédure par défaut de la fenêtre:
	return DefWindowProc(hwnd,message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR szcmd, int ishow)
{
	// Déclaration et initialisation de notre structure WNDCLASSEX:
	WNDCLASSEX wc;
	ZeroMemory(&wc,sizeof(WNDCLASSEX));
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.hInstance=hinst;
	wc.lpszClassName="fenetre";
	wc.lpfnWndProc=WindProc;
	wc.hCursor=LoadCursor(0,IDC_ARROW);
	wc.hIcon=LoadIcon(0,IDI_APPLICATION);
	wc.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);
	// Enregistrement de notre classe de fenêtre:
	RegisterClassEx(&wc);
	// Création de notre fenêtre:
	CreateWindowEx(WS_EX_NOACTIVATE| WS_EX_TOOLWINDOW | WS_EX_TOPMOST,"fenetre","Fenêtre sans focus",WS_VISIBLE | WS_POPUP | WS_DLGFRAME,0,0,290,160,0,0,hinst,0);
	// Boucle des messages:
	MSG msg;
	while(GetMessage(&msg,0,0,0))
	{
		DispatchMessage(&msg);
		TranslateMessage(&msg);
	}
	// Sortie du programme:
	return 0;
}

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.