00001 // 00002 // file: BVThreadFun.cpp 00003 // Thiago C. Martins 00004 // Last Updated: 22/7/1998 00005 // 00006 // Implementation of cBasicViewer thread functions 00007 // 00008 // ViewerThreadProcess: Creates the window and enters a message loop. 00009 // Controled by the TH_MESSAGE messages. 00010 // 00011 // ViewerWndProc: Handles all messages sent to the viewer window 00012 // 00013 00014 #include "cBasicViewer.h" // Declaration of cBasicViewer and BVThread namespace 00015 #include <windows.h> // Win32 API main header 00016 00017 // ViewerThreadProcess function 00018 // Author: Thiago C. Martins 00019 // last updated: 22/7/98 00020 // 00025 // 00026 void BVThread::ViewerThreadProcess(cBasicViewer *pViewer) 00027 { 00028 int width, height; // keeps the size of the window's client area 00029 int DeltaW, DeltaH; // keeps the offset of the size of the window 00030 // required by the borders and caption 00031 HWND hwnd; // Stores the handle of the viewer window 00032 MSG msg; // Keeps a message to be handled 00033 HDC hdc; // Device context of the window's clent area 00034 HBITMAP hbmp; // Handle of the bitmap selected into the memory device context 00035 00036 pViewer->ThreadID=GetCurrentThreadId(); // Retrieves our id in order 00037 // to allow the viewer to 00038 // send us messages. 00039 00040 // Startup: Creates the window and the memory device context 00041 00042 // Get the dimensions of the window's client area 00043 width = pViewer->width; 00044 height = pViewer->height; 00045 00046 // Calculates the offsets required for the borders and caption area 00047 DeltaW = 2*GetSystemMetrics(SM_CXFIXEDFRAME); 00048 DeltaH = 2*GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION); 00049 00050 // Checks if the window class has been registered. If not, register it 00051 if(!cBasicViewer::Registered) cBasicViewer::RegisterViewerClass(); 00052 00053 // Creates the window 00054 hwnd=CreateWindow(cBasicViewer::ClassName, pViewer->title, 00055 BV_WNDSTYLE, 00056 CW_USEDEFAULT, CW_USEDEFAULT, 00057 width+DeltaW, height+DeltaH, (HWND) NULL, 00058 (HMENU) NULL, NULL, (LPVOID) NULL); 00059 pViewer->hwnd = hwnd; 00060 // Stores the pointer to the viewer into the GWL_USERDATA 00061 // of the window. Now, the ViewerWndProc can retrieve the viewer 00062 // associated with the window. 00063 SetWindowLong(hwnd, GWL_USERDATA, (LONG) pViewer); 00064 00065 // Gets the device context of the window's client area 00066 // As the window syle have CS_OWNDC, we don't have to call 00067 // ReleaseDC() 00068 hdc=GetDC(hwnd); 00069 00070 // Gets the DCMutex. Now nobody can draw on the memory device context 00071 WaitForSingleObject(pViewer->DCMutex, INFINITE); 00072 // Creates the memory device contex, compatible with the device context of 00073 // the window's client area 00074 pViewer->hMemDC=CreateCompatibleDC(hdc); 00075 // Creates a bitmap to stores the client area of the window 00076 hbmp=CreateCompatibleBitmap(hdc,width,height); 00077 // Selects the bitmap into the device context 00078 SelectObject(pViewer->hMemDC,hbmp); 00079 00080 // Now, the DCMutex can be released. The object can draw on the memory device context 00081 ReleaseMutex(pViewer->DCMutex); 00082 00083 // Startup finished! 00084 00085 // Gets the RunMutex 00086 WaitForSingleObject(pViewer->RunMutex, INFINITE); 00087 00088 // Enter the message loop 00089 while(GetMessage(&msg, NULL, 0, 0)) { 00090 TranslateMessage(&msg); 00091 if(msg.message==TH_MESSAGE) switch(msg.wParam) { 00092 // Boss has something to us, handle the message 00093 00094 // TH_CHECK message: used for comunication checking 00095 case TH_CHECK: 00096 // We're doing just fine boss, thanks 00097 break; 00098 00099 // TH_DIE message: used for shuting us down! 00100 case TH_DIE: 00101 PostQuitMessage(0); // uh-oh 00102 break; 00103 00104 // TH_SHOW message: used for exhibition of the window 00105 case TH_SHOW: 00106 ShowWindow(pViewer->hwnd, SW_SHOW); // Sets the show state of 00107 // the window to SW_SHOW 00108 break; 00109 00110 // TH_HIDE message: used for hiding the window 00111 case TH_HIDE: 00112 ShowWindow(pViewer->hwnd, SW_HIDE); // Sets the show state of 00113 // the window to SW_HIDE 00114 break; 00115 00116 // TH_UPDATE message: used for repainting the window 00117 case TH_UPDATE: 00118 { 00119 RECT rect; 00120 rect.top = rect.left = 0; 00121 rect.right = width; 00122 rect.bottom = height; 00123 InvalidateRect(hwnd,&rect, false); // Invalidates the client area 00124 } // System will now send a WM_PAINT message 00125 break; 00126 } 00127 else DispatchMessage(&msg); // The message wasn't for us 00128 } 00129 00130 // Shutdown: Destroys the window and the memory device context 00131 00132 // Destroys window 00133 if(pViewer->hwnd) DestroyWindow(pViewer->hwnd); 00134 // Gets the DCMutex for the last time 00135 WaitForSingleObject(pViewer->DCMutex, INFINITE); 00136 // Destroys the memory device context 00137 if(pViewer->hMemDC) DeleteDC(pViewer->hMemDC); 00138 // Destroys the bitmap 00139 if(hbmp) DeleteObject(hbmp); 00140 00141 ReleaseMutex(pViewer->RunMutex); // Time to die 00142 } 00143 00144 // ViewerWndProc function 00145 // Author: Thiago C. Martins 00146 // last updated: 22/7/98 00147 // 00161 // 00162 LRESULT WINAPI BVThread::ViewerWndProc(HWND hWnd, UINT uMsg,\ 00163 UINT uParam, LONG lParam) 00164 { 00165 LONG lRet = 1; // Return value of the function 00166 // zero if don't handled the message, nonzero otherwise 00167 00168 cBasicViewer *Viewer; // Points to the viewer associated with the window 00169 int width, height; // Dimensions of the window 00170 00171 PAINTSTRUCT ps; // Struct filled by BeginPaint 00172 HDC hdc; // Device context of the window's update region 00173 00174 switch (uMsg) { 00175 00176 // WM_PAINT messages: 00177 // We just copy the memory device context into the update region 00178 case WM_PAINT: 00179 // Retrieves the viewer associated with the window 00180 Viewer = (cBasicViewer *)GetWindowLong(hWnd, GWL_USERDATA); 00181 if(!Viewer) { // If the pointer is invalid, repasses the message. 00182 lRet=DefWindowProc(hWnd, uMsg, uParam, lParam); 00183 break; 00184 } 00185 // Try to get the DCMutex 00186 // If we can't get it, there's nothing we can do here. 00187 // In this case, system will keep sending us WM_PAINT messages 00188 // until we get the DCMutex and repaint the window 00189 if(WaitForSingleObject(Viewer->DCMutex, 0)!=WAIT_TIMEOUT) { 00190 // If we can get it, repaint the window 00191 00192 // First, get the window dimensions 00193 width = Viewer->width; 00194 height = Viewer->height; 00195 00196 // Get the device context of the update region 00197 hdc=BeginPaint(hWnd, &ps); 00198 00199 // Copy the memory DC into the update region 00200 BitBlt(hdc,0,0,width,height,Viewer->hMemDC,0,0,SRCCOPY); 00201 00202 // Releases the device context of the update region 00203 EndPaint(hWnd, &ps); 00204 00205 // Releases the DCMutex 00206 ReleaseMutex(Viewer->DCMutex); 00207 } 00208 break; 00209 00210 // WM_CLOSE messages: 00211 // We don't want the window to be actually closed, so we just HIDE the window 00212 case WM_CLOSE: 00213 // Sets the show state of the window to SW_HIDE 00214 ShowWindow(hWnd, SW_HIDE); 00215 break; 00216 00217 // Repasses all other messages to DefWindowProc 00218 default: 00219 lRet = DefWindowProc(hWnd, uMsg, uParam, lParam); 00220 break; 00221 } 00222 return lRet; 00223 }