Loupe simple (win32)

Description

Suite à une question du forum j'ai fait cette petite loupe qui affiche la zone sous la souris avec un facteur 2. Un timer raffraichit la loupe toutes les 50ms.

Source / Exemple :


//***************************************************************************************
// Loupe.cpp :
//
//***************************************************************************************

#include <windows.h>

//=======================================================================================
// Variables globales.
//=======================================================================================
HINSTANCE	g_hAppInstance	= NULL;	// instance de l'application
HWND		g_hWndMainFrame	= NULL;	// fenêtre principale de l'application

//=======================================================================================
// Fonctions du module.
//=======================================================================================
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

//***************************************************************************************
// WinMain :
//***************************************************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
				   int nCmdShow)
{
	// initialisation de l'application
	if(!InitInstance(hInstance, nCmdShow))
		return 0;

	// boucle de messages
	MSG msg;
	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

//***************************************************************************************
// InitInstance :
//***************************************************************************************
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	// sauvegarde instance de l'application
	g_hAppInstance = hInstance;
	char szWndClass[] = "LoupeWnd";
	char szWndTitle[] = "Loupe";

	// initialisation classe de fenêtre
	WNDCLASS wc;
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.hInstance		= g_hAppInstance;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= szWndClass;
	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.style			= CS_HREDRAW|CS_VREDRAW;
	if(!RegisterClass(&wc))
		return FALSE;

	// création de la fenêtre principale
	g_hWndMainFrame = CreateWindowEx(WS_EX_TOPMOST, szWndClass, szWndTitle,
			WS_OVERLAPPED|WS_CAPTION|WS_THICKFRAME|WS_SYSMENU|WS_MINIMIZEBOX,
			0, 0, 200, 200, NULL, NULL, g_hAppInstance, NULL);
	if(g_hWndMainFrame == NULL)
		return FALSE;

	// affichage et mise à jour
	ShowWindow(g_hWndMainFrame, nCmdShow);
	UpdateWindow(g_hWndMainFrame);
	return TRUE;
}

//***************************************************************************************
// WndProc :
//***************************************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	// en fonction du message
	switch(uMsg)
	{
	case WM_CREATE :
		{
			// création timer
			SetTimer(hWnd, 0x100, 50, NULL);
			return 0;
		}
	case WM_DESTROY :
		{
			// suppression du timer, fin de l'application
			KillTimer(hWnd, 0x100);
			PostQuitMessage(0);
			return 0;
		}
	case WM_TIMER :
		{
			// mise à jour de la fenêtre
			InvalidateRect(hWnd, NULL, FALSE);
			UpdateWindow(hWnd);
			return 0;
		}
	case WM_PAINT :
		{
			// début du dessin
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);

			// taille zone cliente
			RECT rcClient;
			GetClientRect(hWnd, &rcClient);
			SIZE sizeDst;
			sizeDst.cx = rcClient.right-rcClient.left;
			sizeDst.cy = rcClient.bottom-rcClient.top;

			// création DC et bitmap en mémoire
			HDC hMemDC = CreateCompatibleDC(hdc);
			HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, sizeDst.cx, sizeDst.cy);
			HBITMAP hOldMemBmp = (HBITMAP) SelectObject(hMemDC, hMemBmp);

			// effacement du fond en blanc
			HBRUSH hBrush = CreateSolidBrush(RGB(0xFF, 0xFF, 0xFF));
			FillRect(hMemDC, &rcClient, hBrush);
			DeleteObject(hBrush);

			// position de la souris et de la fenêtre
			POINT ptMouse;
			GetCursorPos(&ptMouse);
			RECT rcWnd;
			GetWindowRect(hWnd, &rcWnd);

			// faire un zoom de la zone sous la souris
			if(!PtInRect(&rcWnd, ptMouse))
			{
				// zone source
				SIZE sizeSrc;
				sizeSrc.cx = sizeDst.cx/2;
				sizeSrc.cy = sizeDst.cy/2;
				RECT rcSrc;
				rcSrc.left		= ptMouse.x-sizeSrc.cx/2;
				rcSrc.top		= ptMouse.y-sizeSrc.cy/2;
				rcSrc.right		= rcSrc.left+sizeSrc.cx;
				rcSrc.bottom	= rcSrc.top+sizeSrc.cy;

				// récupération DC de l'écran et recopie
				HDC hScreenDC = GetDC(NULL);
				StretchBlt(hMemDC, 0, 0, sizeDst.cx, sizeDst.cy, hScreenDC,
						rcSrc.left, rcSrc.top, sizeSrc.cx, sizeSrc.cy, SRCCOPY);
				ReleaseDC(NULL, hScreenDC);
			}
			
			// recopie du DC en mémoire, libération des ressources
			BitBlt(hdc, 0, 0, sizeDst.cx, sizeDst.cy, hMemDC, 0, 0, SRCCOPY);
			SelectObject(hMemDC, hOldMemBmp);
			DeleteObject(hMemBmp);
			DeleteDC(hMemDC);

			// fin du dessin
			EndPaint(hWnd, &ps);
			return 0;
		}
	}

	// traitement par défaut
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

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.