////////////////////////////////////////////////////////////////////// // Exemple d'utilisation : // - des regions // - des toultips (toultip.cpp) // - de boutons fait a la main (btctrl.cpp) // - de l'icone (tray icon) // // Sylvain Marechal // Rev le 4/12/2003 ////////////////////////////////////////////////////////////////////// #include #include #include #include "resource.h" #include "transp.h" #include "btctrl.h" // Protos static long FAR PASCAL WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); // #define #define WM_SHELLICONNOTIFY (WM_USER + 1) ////////////////////////////////////////////////////////////////////// int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow ) { HWND hWnd; MSG msg; WNDCLASSEX wndclass; // Init controls InitCommonControls(); // Enregistrement de la classe memset( &wndclass, 0, sizeof(WNDCLASSEX) ); wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = GetModuleHandle(NULL); wndclass.hIcon = NULL; wndclass.hIconSm = NULL; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = CreateSolidBrush (GetSysColor (COLOR_MENU)); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "REGIONSTEST"; if (!RegisterClassEx (&wndclass)) { MessageBox (NULL, "RegisterClassEx() failed!", "Error", MB_OK); return (1); } // Creation de la fenetre hWnd = CreateWindow( "REGIONSTEST", "COUCOU", WS_OVERLAPPEDWINDOW, 0, 0, 400, 400, NULL, NULL, hInstance, NULL ); // Affiche la fenetre ShowWindow( hWnd, SW_SHOW ); UpdateWindow( hWnd ); // Boucle des messages while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam; } ////////////////////////////////////////////////////////////////////// long FAR PASCAL WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { static BOOL s_fOneSheet = FALSE; static NOTIFYICONDATA s_tnd; static UINT s_nbIcons = 4; static HICON s_ahIcon[4]; static BOOL s_fClignote; static UINT s_uTimer; static HMENU s_hMenu; static HBITMAP s_hBmpVisage; static BOOL s_lButtonDown; static POINT s_OldPoint; static BITMAP s_bm; switch( message ) { case WM_CREATE : { // Region int b; int cxTitle, cyTitle; HRGN hrgn1, hrgn2, hrgnDest; DWORD dwStyle; // On supprime MAX et MIN dwStyle = GetWindowLong( hWnd, GWL_STYLE ); dwStyle &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); SetWindowLong( hWnd, GWL_STYLE , dwStyle ); // On charge le visage : On recupere les dims de l'img // et on cree une region elliptique s_hBmpVisage = LoadBitmap( GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_VISAGE)); GetObject(s_hBmpVisage, sizeof(s_bm), (LPSTR)&s_bm); cxTitle = GetSystemMetrics(SM_CXFRAME) + 1; cyTitle = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFIXEDFRAME) + 1; hrgn1 = CreateEllipticRgn( cxTitle, cyTitle, s_bm.bmWidth + cxTitle, s_bm.bmHeight + cyTitle); // On fait un trou a la place du nez POINT apt[4] = { {130, 180}, {125, 180}, {115, 210}, {145, 210} }; int nCount = 4; hrgn2 = CreatePolygonRgn( apt, nCount, WINDING/*ALTERNATE */); // XOR pour faire effectivement le trou hrgnDest = CreateRectRgn( 0, 0, 0, 0); CombineRgn( hrgnDest, hrgn1, hrgn2,RGN_XOR ); // Soit au final : b = SetWindowRgn( hWnd, hrgnDest, TRUE ); // Chargement des icones (tray) que l'on va faire clignoter avec un timer s_ahIcon[0] = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0); s_ahIcon[1] = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 16, 16, 0); s_ahIcon[2] = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON3), IMAGE_ICON, 16, 16, 0); s_ahIcon[3] = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON4), IMAGE_ICON, 16, 16, 0); s_fClignote = TRUE; s_uTimer = SetTimer( hWnd, 1, 200, NULL ); // On remplit la structure pour l'icone s_tnd.cbSize = sizeof(NOTIFYICONDATA); s_tnd.hWnd = hWnd; s_tnd.uID = 1; s_tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; s_tnd.uCallbackMessage = WM_SHELLICONNOTIFY; s_tnd.hIcon = s_ahIcon[0]; strcpy( s_tnd.szTip, "Test des régions" ); // Appel de la fction qui ajoute l'icone Shell_NotifyIcon( NIM_ADD, &s_tnd); // On charge le menu s_hMenu = LoadMenu( GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_SYSTRAY) ); // Creation de 2 boutons CreateBtWindow( hWnd, ID_COUCOU, 20, 150, MAKEINTRESOURCE(IDB_COUCOU_ON), MAKEINTRESOURCE(IDB_COUCOU_OFF), MAKEINTRESOURCE(IDB_COUCOU_MOVE) ); CreateBtWindow( hWnd, ID_CLOSE, 180, 150, MAKEINTRESOURCE(IDB_EXIT_ON), MAKEINTRESOURCE(IDB_EXIT_OFF), MAKEINTRESOURCE(IDB_EXIT_MOVE) ); // Gestion de fenetre qui bouge qd on reste clique s_lButtonDown = FALSE; // ToolTips SetBtText( GetDlgItem(hWnd,ID_COUCOU), "Tooltip pour coucou" ); SetBtText( GetDlgItem(hWnd,ID_CLOSE), "Tooltip pour exit" ); break; } // Dessin de la fenetre case WM_PAINT: { HDC hDC, hDCMem; HGDIOBJ hOld; PAINTSTRUCT ps; hDC = BeginPaint( hWnd, &ps ); // Copie de l'image sur l'ecran : Le fait d'avoir defini des regions // est maintenant gere par Windows hDCMem = CreateCompatibleDC(hDC); hOld = SelectObject( hDCMem, s_hBmpVisage ); BitBlt( hDC, 0, 0, s_bm.bmWidth, s_bm.bmHeight, hDCMem, 0, 0, SRCCOPY ); SelectObject( hDCMem, hOld ); ReleaseDC( hWnd, hDCMem ); EndPaint( hWnd, &ps ); return 0L; } // Gestion de la fenetre qui bouge qd on clique dessus // puis qu'on bouge la souris case WM_LBUTTONDOWN: { if( ! s_lButtonDown ) { s_lButtonDown = TRUE; SetCapture( hWnd); GetCursorPos( &s_OldPoint ); } break; } case WM_LBUTTONUP: { if( s_lButtonDown ) { ReleaseCapture(); s_lButtonDown = FALSE; } break; } case WM_MOUSEMOVE: { POINT Point; if( s_lButtonDown ) { RECT rect; int nWidth, nHeight; GetCursorPos( &Point ); GetWindowRect( hWnd, &rect ); nWidth = rect.right - rect.left; nHeight = rect.bottom - rect.top; MoveWindow( hWnd, rect.left + Point.x - s_OldPoint.x, rect.top + Point.y - s_OldPoint.y, nWidth, nHeight, TRUE ); s_OldPoint = Point; } return 0; } // Gestion du clignotement de l'icone case WM_TIMER: { static int s_iIcon = 0; if( s_fClignote ) { // modif de l'icone s_iIcon = (s_iIcon + 1) % s_nbIcons; s_tnd.hIcon = s_ahIcon[s_iIcon]; Shell_NotifyIcon( NIM_MODIFY, &s_tnd); } else { // modif de l'icone s_tnd.hIcon = s_ahIcon[0]; Shell_NotifyIcon( NIM_MODIFY, &s_tnd); } break; } // Traitement des message qd on clique sur l'icone case WM_SHELLICONNOTIFY: { switch( lParam ) { case WM_LBUTTONDBLCLK: { // Si on doubleclick sur l'icone, ca arrete de clignoter/clignote s_fClignote = ! s_fClignote; break; } // On cree le menu qd on click gauche/droit case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: { POINT point; HMENU hSubMenu; // Get mouse pos point.x = LOWORD(lParam); point.y = HIWORD(lParam); GetCursorPos( &point ); // Comme ds le MSDN ... hSubMenu = GetSubMenu( s_hMenu, 0); SetForegroundWindow( hWnd ); TrackPopupMenu( hSubMenu, TPM_LEFTALIGN, point.x, point.y, 0, hWnd, NULL ); PostMessage( hWnd, WM_NULL, 0, 0); break; } } return 0; } // Gestion menu/boutons case WM_COMMAND : { switch(wParam ) { case ID_COUCOU: { MessageBox( hWnd, "coucou", "coucou", MB_OK ); break; } case ID_CLOSE: { SendMessage( hWnd, WM_DESTROY, 0, 0 ); break; } } return 0; } case WM_DESTROY : { // Restons propres KillTimer( hWnd, s_uTimer ); // Eviter que l'icone reste qd on quitte le prog. Shell_NotifyIcon( NIM_DELETE, &s_tnd); // Fin PostQuitMessage( 0 ); return 0L; } } return DefWindowProc( hWnd, message, wParam, lParam ); }