// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact // the authors on vnc@uk.research.att.com for information on obtaining it. // BmpFlasher.cpp: implementation of the BmpFlasher class. #include "stdhdrs.h" #include "vncviewer.h" #include "BmpFlasher.h" #include "Exception.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #define BmpFlasher_CLASS_NAME "VNCviewer BmpFlasher" #define FLASHFONTHEIGHT 80 int m_nTimerID; HBITMAP hbmBkGnd = NULL; HBITMAP DoGetBkGndBitmap2(IN CONST UINT uBmpResId ) { if (NULL == hbmBkGnd) { /*char szFileName[MAX_PATH]; if (GetModuleFileName(NULL, szFileName, MAX_PATH)) { char* p = strrchr(szFileName, '\\'); if (p == NULL) return false; *p = '\0'; strcat (szFileName,"\\flash.bmp"); } hbmBkGnd = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );*/ hbmBkGnd = (HBITMAP)LoadImage( GetModuleHandle(NULL), MAKEINTRESOURCE(uBmpResId), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); if (NULL == hbmBkGnd) hbmBkGnd = (HBITMAP)-1; } return (hbmBkGnd == (HBITMAP)-1) ? NULL : hbmBkGnd; } BOOL DoSDKEraseBkGnd2( IN CONST HDC hDC, IN CONST COLORREF crBkGndFill ) { DoGetBkGndBitmap2(IDB_BITMAP11); if (hDC && hbmBkGnd) { RECT rc; if ((ERROR != GetClipBox(hDC, &rc)) && !IsRectEmpty(&rc)) { HDC hdcMem = CreateCompatibleDC(hDC); if (hdcMem) { HBRUSH hbrBkGnd = CreateSolidBrush(crBkGndFill); if (hbrBkGnd) { HGDIOBJ hbrOld = SelectObject(hDC, hbrBkGnd); if (hbrOld) { SIZE size = { (rc.right-rc.left), (rc.bottom-rc.top) }; if (PatBlt(hDC, rc.left, rc.top, size.cx, size.cy, PATCOPY)) { HGDIOBJ hbmOld = SelectObject(hdcMem, hbmBkGnd); if (hbmOld) { BitBlt(hDC, rc.left, rc.top, size.cx, size.cy, hdcMem, rc.left, rc.top, SRCCOPY); SelectObject(hdcMem, hbmOld); } } SelectObject(hDC, hbrOld); } DeleteObject(hbrBkGnd); } DeleteDC(hdcMem); } } } return TRUE; } BmpFlasher::BmpFlasher() { // Create a dummy window. We don't use it for anything except // receiving socket events, so a seperate listening thread would // probably be easier! WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = BmpFlasher::WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = pApp->m_instance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = (const char *) NULL; wndclass.lpszClassName = BmpFlasher_CLASS_NAME; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); m_hwnd = CreateWindow(BmpFlasher_CLASS_NAME, BmpFlasher_CLASS_NAME, WS_OVERLAPPED | WS_THICKFRAME, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, pApp->m_instance, NULL); SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this); LONG style = GetWindowLong(m_hwnd, GWL_STYLE); style = GetWindowLong(m_hwnd, GWL_STYLE); style &= ~(WS_DLGFRAME | WS_THICKFRAME); SetWindowLong(m_hwnd, GWL_STYLE, style); SetWindowPos(m_hwnd, HWND_TOPMOST, -1, -1, 300, 200, SWP_FRAMECHANGED); CentreWindow(m_hwnd); } // Process window messages LRESULT CALLBACK BmpFlasher::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { // This is a static method, so we don't know which instantiation we're // dealing with. We use Allen Hadden's (ahadden@taratec.com) suggestion // from a newsgroup to get the pseudo-this. BmpFlasher *_this = (BmpFlasher *) GetWindowLong(hwnd, GWL_USERDATA); switch (iMsg) { case WM_ERASEBKGND: { DoSDKEraseBkGnd2((HDC)wParam, RGB(255,0,0)); return true; } case WM_CTLCOLORSTATIC: { SetBkMode((HDC) wParam, TRANSPARENT); return (DWORD) GetStockObject(NULL_BRUSH); } case WM_TIMER: DestroyWindow(hwnd); break; case WM_CREATE: CentreWindow(hwnd); SetForegroundWindow(hwnd); m_nTimerID = SetTimer(hwnd,1, 200, 0); return 0; case WM_CLOSE: KillTimer(hwnd,m_nTimerID); break; case WM_USER: switch (lParam) { case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_KEYDOWN: case WM_MBUTTONDOWN: DestroyWindow(hwnd); KillTimer(hwnd,m_nTimerID); break; } } return DefWindowProc(hwnd, iMsg, wParam, lParam); } void BmpFlasher::Killflash() { if (m_hwnd) DestroyWindow(m_hwnd); m_hwnd=NULL; } BmpFlasher::~BmpFlasher() { if (m_hwnd) DestroyWindow(m_hwnd); m_hwnd=NULL; if (hbmBkGnd) DeleteObject(hbmBkGnd); hbmBkGnd=NULL; }