Win32MainWindow.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // Filename:  Win32MainWindow.cpp
00003 // Author:    Florian Hecht
00004 // Date:      2008
00005 // ****************************************************************************
00006 
00007 
00008 #include "Win32MainWindow.h"
00009 #include "Interfaces/MainWindowEventInterface.h"
00010 
00011 #include <windows.h>
00012 #include <Windowsx.h>
00013 #include <commctrl.h>
00014 
00015 #include "Image/ByteImage.h"
00016 
00017 
00018 enum Win32WidgetType
00019 {
00020         eImage = 0,
00021         eButton,
00022         eLabel,
00023         eCheckBox,
00024         eTextEdit,
00025         eSlider,
00026         eComboBox,
00027         eGLWidget
00028 };
00029 
00030 struct Win32Widget
00031 {
00032         Win32WidgetType m_eType;
00033         int m_index;            // index into the widgets array
00034         HWND m_hWnd;            // window handle
00035 };
00036 
00037 struct Win32ImageWidget : public Win32Widget
00038 {
00039         HDC m_hDC;                                      // device context of the widget
00040         HDC m_hDCMem;                           // device context to store the current image
00041         HBITMAP m_hBmp;                         // the bitmap with the image
00042         HBITMAP m_hBmpOld;                      // the previous bitmap (to restore the state)
00043         unsigned char *m_pPixels;       // pointer to an upside-down BGR buffer
00044         int m_iWidth;                           // width of the current bitmap
00045         int m_iHeight;                          // height of the current bitmap
00046 
00047         const CByteImage *m_pImage;     // the currently displayed image
00048         unsigned char *m_buffer;        // stores a copy of the upside-down BGR buffer
00049                                                                 //   it is used to draw the selection rectangle
00050 
00051         // mouse interaction
00052         bool mouse_down;
00053         unsigned int mouse_start_x;
00054         unsigned int mouse_start_y;
00055         unsigned int mouse_current_x;
00056         unsigned int mouse_current_y;
00057 };
00058 
00059 struct Win32GLWidget : public Win32Widget
00060 {
00061         HDC m_hDC;                                      // device context of the widget
00062         int m_iWidth;                           // width of the current bitmap
00063         int m_iHeight;                          // height of the current bitmap
00064         HGLRC m_hGLRC;                          // OpenGL context
00065 };
00066 
00067 
00068 // helper function
00069 void DrawRect(unsigned char *img, int width, int height, int x0, int y0, int x1, int y1)
00070 {
00071         const int width_ = width % 2 == 0 ? width : width + 1;
00072         int base0 = 3*(height - y0 - 1)*width_;
00073         int base1 = 3*(height - y1)*width_;
00074 
00075         if (x1 >= width)
00076                 x1 = width-1;
00077         if (y1 >= height)
00078                 y1 = height-1;
00079 
00080         for (int x = x0; x < x1; x++)
00081         {
00082                 img[base0 + 3*x + 0] = 255;
00083                 img[base0 + 3*x + 1] = 0;
00084                 img[base0 + 3*x + 2] = 0;
00085 
00086                 img[base1 + 3*x + 0] = 255;
00087                 img[base1 + 3*x + 1] = 0;
00088                 img[base1 + 3*x + 2] = 0;
00089         }
00090 
00091         for (int y = (height - y1); y < (height - y0 - 1); y++)
00092         {
00093                 img[3*y*width_ + 3*x0 + 0] = 255;
00094                 img[3*y*width_ + 3*x0 + 1] = 0;
00095                 img[3*y*width_ + 3*x0 + 2] = 0;
00096 
00097                 img[3*y*width_ + 3*(x1-1) + 0] = 255;
00098                 img[3*y*width_ + 3*(x1-1) + 1] = 0;
00099                 img[3*y*width_ + 3*(x1-1) + 2] = 0;
00100         }
00101 }
00102 
00103 
00104 #define DEFAULT_CLASS_NAME      "MainWindow"
00105 #define IMAGE_WINDOW_CLASS_NAME "ImageWindow"
00106 
00107 LRESULT CALLBACK WndProc(HWND hWnd,     UINT uMsg, WPARAM wParam, LPARAM lParam)
00108 {
00109         if (uMsg == WM_CREATE)
00110         {
00111                 // extract the pointer to the object that created the window
00112                 CREATESTRUCT *cs = (CREATESTRUCT*)lParam;
00113                 CWin32MainWindow *ptr = (CWin32MainWindow*)cs->lpCreateParams;
00114 
00115                 // store it in the user data of the window
00116                 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) ptr);
00117 
00118                 return 0;
00119         }
00120         else
00121         {
00122                 // get the pointer to the object from the user data
00123                 CWin32MainWindow *ptr = (CWin32MainWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
00124 
00125                 // if we got a valid pointer, call the WindowProc method of that object
00126                 if (ptr)
00127                         return ptr->WindowProc(hWnd, uMsg, wParam, lParam);
00128                 else
00129                         return DefWindowProc(hWnd, uMsg, wParam, lParam);
00130         }
00131 }
00132 
00133 
00134 LRESULT CALLBACK CWin32MainWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00135 {
00136         Win32Widget *w = FindWidget(hWnd);
00137 
00138         switch (uMsg)
00139         {
00140                 case WM_ACTIVATE:
00141                         // check minimization state
00142                         //bActive = !HIWORD(wParam);
00143                         return 0;
00144         
00145                 /*case WM_SYSCOMMAND:
00146                         switch (wParam)
00147                         {
00148                                 case SC_SCREENSAVE:
00149                                 case SC_MONITORPOWER:
00150                                 return 0;
00151                         }
00152                         break;*/
00153 
00154                 case WM_CLOSE:
00155                         m_quit_count++;
00156                         m_did_quit = true;
00157 
00158                         if (m_quit_count >= m_ref_count)
00159                                 PostQuitMessage(0);
00160                         else
00161                                 ShowWindow(m_hWnd, SW_HIDE);
00162 
00163                         return 0;
00164 
00165                 case WM_LBUTTONDOWN:
00166                         {
00167                                 if (w != NULL && w->m_eType == eImage)
00168                                 {
00169                                         Win32ImageWidget *iw = (Win32ImageWidget*)w;
00170 
00171                                         unsigned int x = GET_X_LPARAM(lParam);
00172                                         unsigned int y = GET_Y_LPARAM(lParam);
00173 
00174                                         if (iw->mouse_down)
00175                                         {
00176                                                 iw->mouse_down = false;
00177                                         }
00178                                         else
00179                                         {
00180                                                 iw->mouse_start_x = x;
00181                                                 iw->mouse_start_y = y; 
00182                                                 iw->mouse_current_x = iw->mouse_start_x;
00183                                                 iw->mouse_current_y = iw->mouse_start_y;
00184 
00185                                                 if (x < (unsigned int) iw->m_iWidth && y < (unsigned int) iw->m_iHeight)
00186                                                         iw->mouse_down = true;
00187                                         }
00188                                 }
00189                                 
00190                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00191                                 {
00192                                         if (m_event_callback != NULL)
00193                                         {
00194                                                 m_event_callback->MouseDown((WIDGET_HANDLE)w, IVT_LEFT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00195                                         }
00196 
00197                                         SetFocus(hWnd);
00198                                 }
00199                         }
00200                         break;
00201                         
00202                 case WM_RBUTTONDOWN:
00203                         {
00204                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00205                                 {
00206                                         if (m_event_callback != NULL)
00207                                         {
00208                                                 m_event_callback->MouseDown((WIDGET_HANDLE)w, IVT_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00209                                         }
00210 
00211                                         SetFocus(hWnd);
00212                                 }
00213                         }
00214                         break;
00215                         
00216                 case WM_MBUTTONDOWN:
00217                         {
00218                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00219                                 {
00220                                         if (m_event_callback != NULL)
00221                                         {
00222                                                 m_event_callback->MouseDown((WIDGET_HANDLE)w, IVT_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00223                                         }
00224 
00225                                         SetFocus(hWnd);
00226                                 }
00227                         }
00228                         break;
00229 
00230                 case WM_MOUSEMOVE:
00231                         {
00232                                 if (w != NULL && w->m_eType == eImage)
00233                                 {
00234                                         Win32ImageWidget *iw = (Win32ImageWidget*)w;
00235 
00236                                         if (iw->mouse_down)
00237                                         {
00238                                                 unsigned int old_curr_x = iw->mouse_current_x;
00239                                                 unsigned int old_curr_y = iw->mouse_current_y;
00240 
00241                                                 unsigned int x = GET_X_LPARAM(lParam);
00242                                                 unsigned int y = GET_Y_LPARAM(lParam);
00243 
00244                                                 if (x < (unsigned int) iw->m_iWidth && y < (unsigned int) iw->m_iHeight)
00245                                                 {
00246                                                         iw->mouse_current_x = x;
00247                                                         iw->mouse_current_y = y;
00248 
00249                                                         // tell the window it has to redraw the area
00250                                                         RECT            WindowRect;
00251 
00252                                                         unsigned int x0 = iw->mouse_start_x;
00253                                                         unsigned int y0 = iw->mouse_start_y;
00254                                                         unsigned int x1 = iw->mouse_current_x;
00255                                                         unsigned int y1 = iw->mouse_current_y;
00256 
00257                                                         if (x0 > x1)
00258                                                         {
00259                                                                 unsigned int swap = x0;
00260                                                                 x0 = x1;
00261                                                                 x1 = swap;
00262                                                         }
00263                                                         if (y0 > y1)
00264                                                         {
00265                                                                 unsigned int swap = y0;
00266                                                                 y0 = y1;
00267                                                                 y1 = swap;
00268                                                         }
00269 
00270                                                         WindowRect.left = x0;
00271                                                         WindowRect.right = x1;
00272                                                         WindowRect.top = y0;
00273                                                         WindowRect.bottom = y1;
00274 
00275                                                         InvalidateRect(iw->m_hWnd, &WindowRect, false);
00276 
00277                                                         // also invalidate the previous rect
00278                                                         x0 = iw->mouse_start_x;
00279                                                         y0 = iw->mouse_start_y;
00280                                                         x1 = old_curr_x;
00281                                                         y1 = old_curr_y;
00282 
00283                                                         if (x0 > x1)
00284                                                         {
00285                                                                 unsigned int swap = x0;
00286                                                                 x0 = x1;
00287                                                                 x1 = swap;
00288                                                         }
00289                                                         if (y0 > y1)
00290                                                         {
00291                                                                 unsigned int swap = y0;
00292                                                                 y0 = y1;
00293                                                                 y1 = swap;
00294                                                         }
00295 
00296                                                         WindowRect.left = x0;
00297                                                         WindowRect.right = x1;
00298                                                         WindowRect.top = y0;
00299                                                         WindowRect.bottom = y1;
00300 
00301                                                         InvalidateRect(iw->m_hWnd, &WindowRect, false);
00302                                                 }
00303                                         }
00304                                 }
00305                                 
00306                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00307                                 {
00308                                         if (m_event_callback != NULL)
00309                                         {
00310                                                 m_event_callback->MouseMove((WIDGET_HANDLE)w, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00311                                         }
00312                                 }
00313                         }
00314                         
00315                         break;
00316 
00317                 case WM_LBUTTONUP:
00318                         {
00319                                 if (w != NULL && w->m_eType == eImage)
00320                                 {
00321                                         Win32ImageWidget *iw = (Win32ImageWidget*)w;
00322 
00323                                         if (iw->mouse_down)
00324                                         {
00325                                                 iw->mouse_down = false;
00326 
00327                                                 if (m_event_callback != NULL)
00328                                                 {
00329                                                         if (iw->mouse_start_x == iw->mouse_current_x && iw->mouse_start_y == iw->mouse_current_y)
00330                                                         {
00331                                                                 m_event_callback->PointClicked((WIDGET_HANDLE)w, iw->mouse_start_x, iw->mouse_start_y);
00332                                                         }
00333                                                         else
00334                                                         {
00335                                                                 unsigned int x0 = iw->mouse_start_x;
00336                                                                 unsigned int y0 = iw->mouse_start_y;
00337                                                                 unsigned int x1 = iw->mouse_current_x;
00338                                                                 unsigned int y1 = iw->mouse_current_y;
00339 
00340                                                                 if (x0 > x1)
00341                                                                 {
00342                                                                         unsigned int swap = x0;
00343                                                                         x0 = x1;
00344                                                                         x1 = swap;
00345                                                                 }
00346                                                                 if (y0 > y1)
00347                                                                 {
00348                                                                         unsigned int swap = y0;
00349                                                                         y0 = y1;
00350                                                                         y1 = swap;
00351                                                                 }
00352 
00353                                                                 m_event_callback->RectSelected((WIDGET_HANDLE)w, x0, y0, x1, y1);
00354                                                         }
00355                                                 }
00356 
00357                                                 memcpy(iw->m_pPixels, iw->m_buffer, 3*iw->m_iWidth*iw->m_iHeight);
00358                                                 InvalidateRect(iw->m_hWnd, NULL, false);
00359                                         }
00360                                 }
00361                                 
00362                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00363                                 {
00364                                         if (m_event_callback != NULL)
00365                                         {
00366                                                 m_event_callback->MouseUp((WIDGET_HANDLE)w, IVT_LEFT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00367                                         }
00368                                 }
00369                         }
00370                         break;
00371                         
00372                 case WM_RBUTTONUP:
00373                         {
00374                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00375                                 {
00376                                         if (m_event_callback != NULL)
00377                                         {
00378                                                 m_event_callback->MouseUp((WIDGET_HANDLE)w, IVT_RIGHT_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00379                                         }
00380                                 }
00381                         }
00382                         break;
00383                 
00384                 case WM_MBUTTONUP:
00385                         {
00386                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00387                                 {
00388                                         if (m_event_callback != NULL)
00389                                         {
00390                                                 m_event_callback->MouseUp((WIDGET_HANDLE)w, IVT_MIDDLE_BUTTON, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
00391                                         }
00392                                 }
00393                         }
00394                         break;
00395 
00396                 case WM_KEYDOWN:
00397                         {
00398                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00399                                 {
00400                                         if (m_event_callback != NULL)
00401                                         {
00402                                                 char key[2] = {0, 0};
00403                                                 BYTE keys[256];
00404 
00405                                                 GetKeyboardState(keys);
00406 
00407                                                 int c = ToAscii((unsigned int) wParam, MapVirtualKey((unsigned int) wParam, 0), keys, (unsigned short*)key, 0);
00408                                                 if (c == 1)
00409                                                         m_event_callback->KeyDown((WIDGET_HANDLE)w, key[0]);
00410                                                 else
00411                                                         m_event_callback->KeyDown((WIDGET_HANDLE)w, 0);
00412                                         }
00413                                 }
00414                         }
00415                         break;
00416 
00417                 case WM_KEYUP:
00418                         {
00419                                 if (w != NULL && (w->m_eType == eImage || w->m_eType == eGLWidget))
00420                                 {
00421                                         if (m_event_callback != NULL)
00422                                         {
00423                                                 char key[2] = {0, 0};
00424                                                 BYTE keys[256];
00425 
00426                                                 GetKeyboardState(keys);
00427 
00428                                                 int c = ToAscii((unsigned int) wParam, MapVirtualKey((unsigned int) wParam, 0), keys, (unsigned short*)key, 0);
00429                                                 if (c == 1)
00430                                                         m_event_callback->KeyUp((WIDGET_HANDLE)w, key[0]);
00431                                                 else
00432                                                         m_event_callback->KeyUp((WIDGET_HANDLE)w, 0);
00433                                         }
00434                                 }
00435                         }
00436                         break;
00437 
00438                 case WM_COMMAND:
00439                         {
00440                                 int idx = LOWORD(wParam); // the index into the widgets array
00441                                 int cmd = HIWORD(wParam); // the index into the widgets array
00442 
00443                                 // make sure it's a valid index
00444                                 const int nSize = (int) m_widgets.size();
00445                                 if (idx != 0 && idx > 0 && idx <= nSize)
00446                                 {
00447                                         w = m_widgets[idx-1];
00448 
00449                                         if (w != NULL)
00450                                         {
00451                                                 if (w->m_eType == eButton)
00452                                                 {
00453                                                         if (m_event_callback != NULL)
00454                                                         {
00455                                                                 m_event_callback->ButtonPushed((WIDGET_HANDLE)w);
00456                                                         }
00457         
00458                                                         return 0;
00459                                                 }
00460                                                 else if (w->m_eType == eCheckBox)
00461                                                 {
00462                                                         if (m_event_callback != NULL)
00463                                                         {
00464                                                                 BOOL checked = IsDlgButtonChecked(m_hWnd, idx);
00465 
00466                                                                 m_event_callback->ValueChanged((WIDGET_HANDLE)w, (checked ? 1 : 0));
00467                                                         }
00468         
00469                                                         return 0;
00470                                                 }
00471                                                 else if (w->m_eType == eTextEdit && cmd == EN_CHANGE)
00472                                                 {
00473                                                         if (m_event_callback != NULL)
00474                                                         {
00475                                                                 m_event_callback->ValueChanged((WIDGET_HANDLE)w, -1);
00476                                                         }
00477         
00478                                                         return 0;
00479                                                 }
00480                                                 else if (w->m_eType == eComboBox && cmd == CBN_SELCHANGE)
00481                                                 {
00482                                                         if (m_event_callback != NULL)
00483                                                         {
00484                                                                 int value = (int) SendMessage(w->m_hWnd, CB_GETCURSEL, 0, 0);
00485 
00486                                                                 m_event_callback->ValueChanged((WIDGET_HANDLE)w, value);
00487                                                         }
00488         
00489                                                         return 0;
00490                                                 }
00491                                         }
00492                                 }
00493                         }
00494                         break;
00495 
00496                 case WM_NOTIFY:
00497                         {
00498                                 int idx = (int) wParam; // the index into the widgets array
00499                                 NMHDR *nmhdr = (LPNMHDR)lParam;
00500 
00501                                 // make sure it's a valid index
00502                                 const int nSize = (int) m_widgets.size();
00503                                 if (idx != 0 && idx > 0 && idx <= nSize)
00504                                 {
00505                                         w = m_widgets[idx-1];
00506 
00507                                         if (w != NULL)
00508                                         {
00509                                                 if (w->m_eType == eSlider)
00510                                                 {
00511                                                         if (m_event_callback != NULL && nmhdr->code == -12 /* code for dragging */)
00512                                                         {
00513                                                                 int value = (int) SendMessage(w->m_hWnd, TBM_GETPOS, 0, 0);
00514 
00515                                                                 m_event_callback->ValueChanged((WIDGET_HANDLE)w, value);
00516                                                         }
00517         
00518                                                         return 0;
00519                                                 }
00520                                         }
00521                                 }
00522                         }
00523                         break;
00524 
00525                 case WM_SIZE:
00526                         break;
00527 
00528                 case WM_PAINT:
00529                         {
00530                                 if (w != NULL && w->m_eType == eImage)
00531                                 {
00532                                         Win32ImageWidget *iw = (Win32ImageWidget*)w;
00533 
00534                                         if (iw->m_hBmp != 0)
00535                                         {
00536                                                 PAINTSTRUCT ps;
00537                                                 HDC dc = BeginPaint(iw->m_hWnd, &ps);
00538 
00539                                                 if (iw->mouse_down && (iw->mouse_start_x != iw->mouse_current_x || iw->mouse_start_y != iw->mouse_current_y))
00540                                                 {
00541                                                         unsigned int x0 = iw->mouse_start_x;
00542                                                         unsigned int y0 = iw->mouse_start_y;
00543                                                         unsigned int x1 = iw->mouse_current_x;
00544                                                         unsigned int y1 = iw->mouse_current_y;
00545 
00546                                                         if (x0 > x1)
00547                                                         {
00548                                                                 unsigned int swap = x0;
00549                                                                 x0 = x1;
00550                                                                 x1 = swap;
00551                                                         }
00552                                                         if (y0 > y1)
00553                                                         {
00554                                                                 unsigned int swap = y0;
00555                                                                 y0 = y1;
00556                                                                 y1 = swap;
00557                                                         }
00558 
00559                                                         memcpy(iw->m_pPixels, iw->m_buffer, 3*iw->m_iWidth*iw->m_iHeight);
00560                                                         DrawRect(iw->m_pPixels, iw->m_iWidth, iw->m_iHeight, x0, y0, x1, y1);
00561                                                 }
00562                                                 
00563 
00564                                                 BitBlt(dc, 0, 0, iw->m_iWidth, iw->m_iHeight, iw->m_hDCMem, 0, 0, SRCCOPY);
00565 
00566                                                 EndPaint(w->m_hWnd, &ps);
00567 
00568                                                 return 0;
00569                                         }
00570                                 }
00571                         }
00572 
00573                         break;
00574         }
00575         
00576         // pass all unhandled messages to DefWindowProc
00577         return DefWindowProc(hWnd, uMsg, wParam, lParam);
00578 }
00579 
00580 int CWin32MainWindow::m_ref_count = 0;
00581 int CWin32MainWindow::m_quit_count = 0;
00582 
00583 CWin32MainWindow::CWin32MainWindow(int x, int y, int width, int height, const char *title)
00584 {
00585         m_did_quit = false;
00586 
00587         WNDCLASS        wc;                                             // Windows Class Structure
00588         DWORD           dwExStyle;                              // Window Extended Style
00589         DWORD           dwStyle;                                // Window Style
00590         RECT            WindowRect;                             // Grabs Rectangle Upper Left / Lower Right Values
00591 
00592         WindowRect.left = x;
00593         WindowRect.right = x + width;
00594         WindowRect.top = y;
00595         WindowRect.bottom = y + height;
00596 
00597         m_hInstance = GetModuleHandle(NULL);
00598 
00599         if (m_ref_count == 0)
00600         {
00601                 wc.style                        = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;       // Redraw On Size, And Own DC For Window.
00602                 wc.lpfnWndProc          = (WNDPROC) WndProc;                                    // WndProc Handles Messages
00603                 wc.cbClsExtra           = 0;                                                                    // No Extra Class Data
00604                 wc.cbWndExtra           = 8;                                                                    // 4 bytes of Extra Window Data
00605                 wc.hInstance            = m_hInstance;                                                  // Set The Instance
00606                 wc.hIcon                        = LoadIcon(NULL, IDI_WINLOGO);                  // Load The Default Icon
00607                 wc.hCursor                      = LoadCursor(NULL, IDC_ARROW);                  // Load The Arrow Pointer
00608                 wc.hbrBackground        = GetSysColorBrush(COLOR_BTNFACE);      // Background
00609                 wc.lpszMenuName         = NULL;                                                                 // We Don't Want A Menu
00610                 wc.lpszClassName        = DEFAULT_CLASS_NAME;                                   // Set The Class Name
00611 
00612                 if (!RegisterClass(&wc))
00613                 {
00614                         MessageBox(NULL,"Failed To Register The MainWindow Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
00615                         return;
00616                 }
00617         
00618 
00619                 wc.style                        = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redraw On Size, And Own DC For Window.
00620                 wc.lpfnWndProc          = (WNDPROC) WndProc;                                    // WndProc Handles Messages
00621                 wc.cbClsExtra           = 0;                                                                    // No Extra Class Data
00622                 wc.cbWndExtra           = 8;                                                                    // 4 bytes of Extra Window Data
00623                 wc.hInstance            = m_hInstance;                                                  // Set The Instance
00624                 wc.hIcon                        = LoadIcon(NULL, IDI_WINLOGO);                  // Load The Default Icon
00625                 wc.hCursor                      = LoadCursor(NULL, IDC_ARROW);                  // Load The Arrow Pointer
00626                 wc.hbrBackground        = NULL; //GetSysColorBrush(COLOR_BTNFACE);              // No Background Required For GL
00627                 wc.lpszMenuName         = NULL;                                                                 // We Don't Want A Menu
00628                 wc.lpszClassName        = IMAGE_WINDOW_CLASS_NAME;                                      // Set The Class Name
00629 
00630                 if (!RegisterClass(&wc))
00631                 {
00632                         MessageBox(NULL,"Failed To Register The Image Window Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
00633                         return;
00634                 }
00635         }
00636 
00637         m_ref_count++;
00638         
00639         dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
00640         dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
00641 
00642         AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);             // Adjust Window To True Requested Size
00643         
00644         // make sure the window is positioned within the desktop
00645         if (WindowRect.top < 0)
00646         {
00647                 WindowRect.bottom -= WindowRect.top;
00648                 WindowRect.top = 0;
00649         }
00650         if (WindowRect.left < 0)
00651         {
00652                 WindowRect.right -= WindowRect.left;
00653                 WindowRect.left = 0;
00654         }
00655 
00656         // Create The Window
00657         if (!(m_hWnd = CreateWindowEx(dwExStyle,                                                // Extended Style For The Window
00658                                                                 DEFAULT_CLASS_NAME,                                     // Class Name
00659                                                                 title,                                                          // Window Title
00660                                                                 dwStyle |                                                       // Defined Window Style
00661                                                                 WS_CLIPSIBLINGS |                                       // Required Window Style
00662                                                                 WS_CLIPCHILDREN,                                        // Required Window Style
00663                                                                 WindowRect.left, WindowRect.top,        // Window Position
00664                                                                 WindowRect.right-WindowRect.left,       // Calculate Window Width
00665                                                                 WindowRect.bottom-WindowRect.top,       // Calculate Window Height
00666                                                                 NULL,                                                           // No Parent Window
00667                                                                 NULL,                                                           // No Menu
00668                                                                 m_hInstance,                                            // Instance
00669                                                                 this)))                                                         // Pass this pointer to WM_CREATE
00670         {
00671                 MessageBox(NULL, "Couldn't create window.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00672                 return;
00673         }
00674 
00675         m_event_callback = NULL;
00676 
00677         //ShowWindow(m_hWnd, SW_SHOW);
00678         SetForegroundWindow(m_hWnd);
00679         SetFocus(m_hWnd);
00680 }
00681 
00682 CWin32MainWindow::~CWin32MainWindow()
00683 {
00684         int i, c = (int) m_widgets.size();
00685 
00686         for (i = c - 1; i >= 0; i--)
00687         {
00688                 Win32Widget *w = m_widgets[i];
00689 
00690                 if (w->m_eType == eImage)
00691                 {
00692                         Win32ImageWidget *iw = (Win32ImageWidget*)w;
00693 
00694                         if (iw->m_buffer != NULL)
00695                         {
00696                                 delete [] iw->m_buffer;
00697                                 iw->m_buffer = NULL;
00698                         }
00699 
00700                         if (iw->m_hBmp != NULL)
00701                         {
00702                                 SelectObject(iw->m_hDCMem, iw->m_hBmpOld);
00703                                 DeleteObject(iw->m_hBmp);
00704 
00705                                 iw->m_hBmp = 0;
00706                                 iw->m_hBmpOld = 0;
00707                         }
00708 
00709                         if (iw->m_hDCMem && !DeleteDC(iw->m_hDCMem))
00710                         {
00711                                 MessageBox(NULL, "Release Compatible Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00712                                 iw->m_hDCMem = NULL;
00713                         }
00714 
00715                         if (iw->m_hDC && !ReleaseDC(iw->m_hWnd, iw->m_hDC))
00716                         {
00717                                 MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00718                                 iw->m_hDC = NULL;
00719                         }
00720                 }
00721 
00722                 if (w->m_eType == eGLWidget)
00723                 {
00724                         Win32GLWidget *glw = (Win32GLWidget*)w;
00725 
00726                         wglMakeCurrent(NULL, NULL);
00727 
00728                         if (glw->m_hGLRC && !wglDeleteContext(glw->m_hGLRC))
00729                         {
00730                                 MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00731                                 glw->m_hGLRC = NULL;
00732                         }
00733 
00734                         if (glw->m_hDC && !ReleaseDC(glw->m_hWnd, glw->m_hDC))
00735                         {
00736                                 MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00737                                 glw->m_hDC = NULL;
00738                         }
00739                 }
00740 
00741                 if (w->m_hWnd && !DestroyWindow(w->m_hWnd))
00742                 {
00743                         MessageBox(NULL,"Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00744                         w->m_hWnd = NULL;
00745                 }
00746 
00747                 delete w;
00748         }
00749 
00750         m_widgets.clear();
00751 
00752         if (m_hWnd && !DestroyWindow(m_hWnd))
00753         {
00754                 MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00755                 m_hWnd = NULL;
00756         }
00757 
00758         m_ref_count--;
00759         if (m_did_quit)
00760                 m_quit_count--;
00761 
00762         if (m_ref_count == 0 && m_hInstance)
00763         {
00764                 if (!UnregisterClass(DEFAULT_CLASS_NAME, m_hInstance) || !UnregisterClass(IMAGE_WINDOW_CLASS_NAME, m_hInstance))
00765                 {
00766                         MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
00767                         m_hInstance = NULL;
00768                 }
00769         }
00770 }
00771 
00772 // create widgets
00773 WIDGET_HANDLE CWin32MainWindow::AddImage(int x, int y, int width, int height, WIDGET_HANDLE parent)
00774 {
00775         Win32Widget *p = (Win32Widget*)parent;
00776 
00777         Win32ImageWidget *iw = new Win32ImageWidget;
00778 
00779         iw->m_eType = eImage;
00780         iw->m_hWnd = 0;
00781         iw->m_hDC = 0;
00782         iw->m_hDCMem = 0;
00783         iw->m_hBmp = 0;
00784         iw->m_hBmpOld = 0;
00785         iw->m_pPixels = NULL;
00786         iw->m_iWidth = 0;
00787         iw->m_iHeight = 0;
00788         iw->m_pImage = NULL;
00789         iw->m_buffer = NULL;
00790 
00791         iw->mouse_down = false;
00792         iw->mouse_start_x = 0;
00793         iw->mouse_start_y = 0;
00794         iw->mouse_current_x = 0;
00795         iw->mouse_current_y = 0;
00796 
00797         // Create The Window
00798         if (!(iw->m_hWnd = CreateWindowEx(0,                                                    // Extended Style For The Window
00799                                                                 IMAGE_WINDOW_CLASS_NAME,                        // Class Name
00800                                                                 "",                                                                     // Window Title
00801                                                                 WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE,                                // Required Window Style
00802                                                                 x, y,                                                           // Window Position
00803                                                                 width,                                                          // Calculate Window Width
00804                                                                 height,                                                         // Calculate Window Height
00805                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
00806                                                                 NULL,                                                           // No Menu
00807                                                                 m_hInstance,                                            // Instance
00808                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
00809         {
00810                 MessageBox(NULL, "Couldn't create image window.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00811                 delete iw;
00812                 return 0;
00813         }
00814 
00815         SetWindowPos(iw->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00816 
00817         if (!(iw->m_hDC = GetDC(iw->m_hWnd)))
00818         {
00819                 MessageBox(NULL, "Couldn't create device context." , "ERROR", MB_OK | MB_ICONEXCLAMATION);
00820                 delete iw;
00821                 return 0;
00822         }
00823 
00824         if (!(iw->m_hDCMem = CreateCompatibleDC(iw->m_hDC)))
00825         {
00826                 MessageBox(NULL, "Couldn't create compatible device context." , "ERROR", MB_OK | MB_ICONEXCLAMATION);
00827                 delete iw;
00828                 return 0;
00829         }
00830 
00831         iw->m_index = (int) m_widgets.size();
00832         m_widgets.push_back(iw);
00833 
00834         return (WIDGET_HANDLE) iw;
00835 }
00836 
00837 WIDGET_HANDLE CWin32MainWindow::AddButton(int x, int y, int width, int height, const char *text, WIDGET_HANDLE parent)
00838 {
00839         Win32Widget *p = (Win32Widget*)parent;
00840 
00841         Win32Widget *w = new Win32Widget;
00842 
00843         w->m_eType = eButton;
00844         w->m_hWnd = 0;
00845 
00846         // Create The Window
00847         if (!(w->m_hWnd = CreateWindowEx(0,                                                             // Extended Style For The Window
00848                                                                 "button",                                                       // Class Name
00849                                                                 text,                                                           // Window Title
00850                                                                 WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE,                                // Required Window Style
00851                                                                 x, y,                                                           // Window Position
00852                                                                 width,                                                          // Calculate Window Width
00853                                                                 height,                                                         // Calculate Window Height
00854                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
00855                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
00856                                                                 m_hInstance,                                            // Instance
00857                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
00858         {
00859                 MessageBox(NULL, "Couldn't create button.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00860 
00861                 delete w;
00862 
00863                 return 0;
00864         }
00865 
00866         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00867 
00868         w->m_index = (int) m_widgets.size();
00869         m_widgets.push_back(w);
00870 
00871         return (WIDGET_HANDLE)w;
00872 }
00873 
00874 WIDGET_HANDLE CWin32MainWindow::AddLabel(int x, int y, int width, int height, const char *text, WIDGET_HANDLE parent)
00875 {
00876         Win32Widget *p = (Win32Widget*)parent;
00877 
00878         Win32Widget *w = new Win32Widget;
00879 
00880         w->m_eType = eLabel;
00881         w->m_hWnd = 0;
00882 
00883         // Create The Window
00884         if (!(w->m_hWnd = CreateWindowEx(0,                                                             // Extended Style For The Window
00885                                                                 "STATIC",                                                       // Class Name
00886                                                                 text,                                                           // Window Title
00887                                                                 WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE,                                // Required Window Style
00888                                                                 x, y,                                                           // Window Position
00889                                                                 width,                                                          // Calculate Window Width
00890                                                                 height,                                                         // Calculate Window Height
00891                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
00892                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
00893                                                                 m_hInstance,                                            // Instance
00894                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
00895         {
00896                 MessageBox(NULL, "Couldn't create label.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00897 
00898                 delete w;
00899 
00900                 return 0;
00901         }
00902 
00903         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00904 
00905         w->m_index = (int) m_widgets.size();
00906         m_widgets.push_back(w);
00907 
00908         return (WIDGET_HANDLE)w;
00909 }
00910 
00911 WIDGET_HANDLE CWin32MainWindow::AddCheckBox(int x, int y, int width, int height, const char *text, bool checked, WIDGET_HANDLE parent)
00912 {
00913         Win32Widget *p = (Win32Widget*)parent;
00914 
00915         Win32Widget *w = new Win32Widget;
00916 
00917         w->m_eType = eCheckBox;
00918         w->m_hWnd = 0;
00919 
00920         // Create The Window
00921         if (!(w->m_hWnd = CreateWindowEx(0,                                                             // Extended Style For The Window
00922                                                                 "button",                                                       // Class Name
00923                                                                 text,                                                           // Window Title
00924                                                                 WS_CHILD | WS_VISIBLE | BS_CHECKBOX | BS_AUTOCHECKBOX,// Required Window Style
00925                                                                 x, y,                                                           // Window Position
00926                                                                 width,                                                          // Calculate Window Width
00927                                                                 height,                                                         // Calculate Window Height
00928                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
00929                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
00930                                                                 m_hInstance,                                            // Instance
00931                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
00932         {
00933                 MessageBox(NULL, "Couldn't create check box.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00934 
00935                 delete w;
00936 
00937                 return 0;
00938         }
00939 
00940         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00941 
00942         w->m_index = (int) m_widgets.size();
00943         m_widgets.push_back(w);
00944 
00945         if (checked)
00946                 CheckDlgButton(m_hWnd, w->m_index+1, BST_CHECKED);
00947         else
00948                 CheckDlgButton(m_hWnd, w->m_index+1, BST_UNCHECKED);
00949 
00950         return (WIDGET_HANDLE)w;
00951 }
00952 
00953 WIDGET_HANDLE CWin32MainWindow::AddTextEdit(int x, int y, int width, int height, const char *text, WIDGET_HANDLE parent)
00954 {
00955         Win32Widget *p = (Win32Widget*)parent;
00956 
00957         Win32Widget *w = new Win32Widget;
00958 
00959         w->m_eType = eTextEdit;
00960         w->m_hWnd = 0;
00961 
00962         // Create The Window
00963         if (!(w->m_hWnd = CreateWindowEx(WS_EX_STATICEDGE,                              // Extended Style For The Window
00964                                                                 "Edit",                                                         // Class Name
00965                                                                 text,                                                           // Window Title
00966                                                                 WS_CHILD | WS_VISIBLE | WS_BORDER,      // Required Window Style
00967                                                                 x, y,                                                           // Window Position
00968                                                                 width,                                                          // Calculate Window Width
00969                                                                 height,                                                         // Calculate Window Height
00970                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
00971                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
00972                                                                 m_hInstance,                                            // Instance
00973                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
00974         {
00975                 MessageBox(NULL, "Couldn't create text edit.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
00976 
00977                 delete w;
00978 
00979                 return 0;
00980         }
00981 
00982         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00983 
00984         w->m_index = (int) m_widgets.size();
00985         m_widgets.push_back(w);
00986 
00987         return (WIDGET_HANDLE)w;
00988 }
00989 
00990 WIDGET_HANDLE CWin32MainWindow::AddSlider(int x, int y, int width, int height, int min_value, int max_value, int step, int value, WIDGET_HANDLE parent)
00991 {
00992         Win32Widget *p = (Win32Widget*)parent;
00993 
00994         Win32Widget *w = new Win32Widget;
00995 
00996         w->m_eType = eSlider;
00997         w->m_hWnd = 0;
00998 
00999         // Create The Window
01000         if (!(w->m_hWnd = CreateWindowEx(0,                                                             // Extended Style For The Window
01001                                                                 TRACKBAR_CLASS,                                         // Class Name
01002                                                                 "Trackbar",                                                             // Window Title
01003                                                                 WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS,  // Required Window Style
01004                                                                 x, y,                                                           // Window Position
01005                                                                 width,                                                          // Calculate Window Width
01006                                                                 height,                                                         // Calculate Window Height
01007                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
01008                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
01009                                                                 m_hInstance,                                            // Instance
01010                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
01011         {
01012                 MessageBox(NULL, "Couldn't create text edit.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
01013 
01014                 delete w;
01015 
01016                 return 0;
01017         }
01018 
01019         SendMessage(w->m_hWnd, TBM_SETRANGE,  TRUE,  MAKELONG(min_value, max_value)); 
01020         SendMessage(w->m_hWnd, TBM_SETPAGESIZE, 0,  step); 
01021         SendMessage(w->m_hWnd, TBM_SETTICFREQ, step, 0); 
01022         SendMessage(w->m_hWnd, TBM_SETPOS, TRUE, value); 
01023 
01024         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
01025 
01026         w->m_index = (int) m_widgets.size();
01027         m_widgets.push_back(w);
01028 
01029         return (WIDGET_HANDLE)w;
01030 }
01031 
01032 WIDGET_HANDLE CWin32MainWindow::AddComboBox(int x, int y, int width, int height, int num_entries, const char **entries, int current_entry, WIDGET_HANDLE parent)
01033 {
01034         Win32Widget *p = (Win32Widget*)parent;
01035 
01036         Win32Widget *w = new Win32Widget;
01037 
01038         w->m_eType = eComboBox;
01039         w->m_hWnd = 0;
01040 
01041         // Create The Window
01042         if (!(w->m_hWnd = CreateWindowEx(0,                                                             // Extended Style For The Window
01043                                                                 "combobox",                                                     // Class Name
01044                                                                 "ComboBox",                                                     // Window Title
01045                                                                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,  // Required Window Style
01046                                                                 x, y,                                                           // Window Position
01047                                                                 width,                                                          // Calculate Window Width
01048                                                                 2*width,                                                        // HACK: in win32 the height should incorporate the extended drop down list
01049                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
01050                                                                 (HMENU)(m_widgets.size()+1),            // The index into the widgets array is stored as the button id
01051                                                                 m_hInstance,                                            // Instance
01052                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
01053         {
01054                 MessageBox(NULL, "Couldn't create text edit.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
01055 
01056                 delete w;
01057 
01058                 return 0;
01059         }
01060 
01061         for (int i = 0; i < num_entries; i++)
01062         {
01063                 SendMessage(w->m_hWnd, CB_ADDSTRING, 0, (LPARAM)entries[i]);
01064         }
01065 
01066         SendMessage(w->m_hWnd, CB_SETCURSEL, current_entry, 0);
01067 
01068         SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
01069 
01070         w->m_index = (int) m_widgets.size();
01071         m_widgets.push_back(w);
01072 
01073         return (WIDGET_HANDLE)w;
01074 }
01075 
01076 WIDGET_HANDLE CWin32MainWindow::AddGLWidget(int x, int y, int width, int height, WIDGET_HANDLE parent)
01077 {
01078         Win32Widget *p = (Win32Widget*)parent;
01079 
01080         Win32GLWidget *glw = new Win32GLWidget;
01081 
01082         glw->m_eType = eGLWidget;
01083         glw->m_hWnd = 0;
01084         glw->m_hDC = 0;
01085         glw->m_iWidth = width;
01086         glw->m_iHeight = height;
01087 
01088         // Create The Window
01089         if (!(glw->m_hWnd = CreateWindowEx(0,                                                   // Extended Style For The Window
01090                                                                 IMAGE_WINDOW_CLASS_NAME,                        // Class Name (re-use the image window class
01091                                                                 "",                                                                     // Window Title
01092                                                                 WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE,                                // Required Window Style
01093                                                                 x, y,                                                           // Window Position
01094                                                                 width,                                                          // Calculate Window Width
01095                                                                 height,                                                         // Calculate Window Height
01096                                                                 (p != 0 ? p->m_hWnd : m_hWnd),          // Parent Window
01097                                                                 NULL,                                                           // No Menu
01098                                                                 m_hInstance,                                            // Instance
01099                                                                 this)))                                                         // Pass pointer to struct to WM_CREATE
01100         {
01101                 MessageBox(NULL, "Couldn't create image window.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
01102 
01103                 delete glw;
01104 
01105                 return 0;
01106         }
01107 
01108         SetWindowPos(glw->m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
01109 
01110         if (!(glw->m_hDC = GetDC(glw->m_hWnd)))
01111         {
01112                 MessageBox(NULL, "Couldn't create device context." , "ERROR", MB_OK | MB_ICONEXCLAMATION);
01113 
01114                 delete glw;
01115 
01116                 return 0;
01117         }
01118 
01119         PIXELFORMATDESCRIPTOR pfd = { 
01120                 sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd 
01121                 1,                     // version number 
01122                 PFD_DRAW_TO_WINDOW |   // support window 
01123                 PFD_SUPPORT_OPENGL |   // support OpenGL 
01124                 PFD_DOUBLEBUFFER,      // double buffered 
01125                 PFD_TYPE_RGBA,         // RGBA type 
01126                 24,                    // 24-bit color depth 
01127                 0, 0, 0, 0, 0, 0,      // color bits ignored 
01128                 0,                     // no alpha buffer 
01129                 0,                     // shift bit ignored 
01130                 0,                     // no accumulation buffer 
01131                 0, 0, 0, 0,            // accum bits ignored 
01132                 32,                    // 32-bit z-buffer 
01133                 0,                     // no stencil buffer 
01134                 0,                     // no auxiliary buffer 
01135                 PFD_MAIN_PLANE,        // main layer 
01136                 0,                     // reserved 
01137                 0, 0, 0                // layer masks ignored 
01138         }; 
01139         
01140         int  iPixelFormat; 
01141  
01142         // get the best available match of pixel format for the device context  
01143         iPixelFormat = ChoosePixelFormat(glw->m_hDC, &pfd); 
01144  
01145         // make that the pixel format of the device context 
01146         BOOL bResult = SetPixelFormat(glw->m_hDC, iPixelFormat, &pfd);
01147         if (!bResult)
01148         {
01149                 MessageBox(NULL, "ERROR: SetPixelFormat failed", "ERROR", MB_OK | MB_ICONEXCLAMATION);
01150 
01151                 delete glw;
01152 
01153                 return NULL;
01154         }
01155         
01156         glw->m_hGLRC = wglCreateContext(glw->m_hDC);
01157         if (!glw->m_hGLRC)
01158         {
01159                 MessageBox(NULL, "ERROR: couldn't allocate HGLRC", "ERROR", MB_OK | MB_ICONEXCLAMATION);
01160 
01161                 glw;
01162 
01163                 return NULL;
01164         }
01165 
01166         wglMakeCurrent(glw->m_hDC, glw->m_hGLRC);
01167 
01168         glw->m_index = (int) m_widgets.size();
01169         m_widgets.push_back(glw);
01170 
01171         return (WIDGET_HANDLE)glw;
01172 }
01173 
01174 
01175 
01176 // access to widget attributes
01177 bool CWin32MainWindow::GetText(WIDGET_HANDLE widget, char *text, int len)
01178 {
01179         Win32Widget *w = (Win32Widget*)widget;
01180 
01181         if (w->m_eType == eButton || w->m_eType == eCheckBox)
01182         {
01183                 Button_GetText(w->m_hWnd, text, len);
01184         }
01185         else if (w->m_eType == eLabel)
01186         {
01187                 Static_GetText(w->m_hWnd, text, len);
01188         }
01189         else if (w->m_eType == eTextEdit)
01190         {
01191                 GetWindowText(w->m_hWnd, text, len);
01192         }
01193         else
01194                 return false;
01195 
01196         return true;
01197 }
01198 bool CWin32MainWindow::SetText(WIDGET_HANDLE widget, const char *text)
01199 {
01200         Win32Widget *w = (Win32Widget*)widget;
01201 
01202         if (w->m_eType == eButton || w->m_eType == eCheckBox)
01203         {
01204                 Button_SetText(w->m_hWnd, text);
01205         }
01206         else if (w->m_eType == eLabel)
01207         {
01208                 Static_SetText(w->m_hWnd, text);
01209         }
01210         else if (w->m_eType == eTextEdit)
01211         {
01212                 SetWindowText(w->m_hWnd, text);
01213         }
01214         else
01215                 return false;
01216 
01217         return true;
01218 }
01219 
01220 bool CWin32MainWindow::SetImage(WIDGET_HANDLE widget, const CByteImage *pImage)
01221 {
01222         Win32Widget *w = (Win32Widget*)widget;
01223 
01224         if (w->m_eType == eImage)
01225         {
01226                 Win32ImageWidget *iw = (Win32ImageWidget*)w;
01227 
01228                 iw->m_pImage = pImage;
01229 
01230                 if (iw->m_iWidth != pImage->width || iw->m_iHeight != pImage->height)
01231                 {
01232                         if (iw->m_hBmp != 0)
01233                         {
01234                                 SelectObject(iw->m_hDCMem, iw->m_hBmpOld);
01235                                 DeleteObject(iw->m_hBmp);
01236 
01237                                 iw->m_hBmp = 0;
01238                                 iw->m_hBmpOld = 0;
01239                         }
01240 
01241                         if (iw->m_buffer != NULL)
01242                         {
01243                                 delete [] iw->m_buffer;
01244                                 iw->m_buffer = NULL;
01245                         }
01246 
01247                         BITMAPINFO bminfo;
01248                         // create a bitmap with rgb pixels
01249                         bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01250                         bminfo.bmiHeader.biWidth = pImage->width;
01251                         bminfo.bmiHeader.biHeight = pImage->height;
01252                         bminfo.bmiHeader.biPlanes = 1;
01253                         bminfo.bmiHeader.biBitCount = 24;
01254                         bminfo.bmiHeader.biCompression = BI_RGB;
01255                         bminfo.bmiHeader.biSizeImage = 0; // it's OK for RGB images
01256                         bminfo.bmiHeader.biXPelsPerMeter = 1;
01257                         bminfo.bmiHeader.biYPelsPerMeter = 1;
01258                         bminfo.bmiHeader.biClrUsed = 0;
01259                         bminfo.bmiHeader.biClrImportant = 0;
01260 
01261                         iw->m_hBmp = CreateDIBSection(iw->m_hDC, &bminfo, DIB_RGB_COLORS, (void**)&iw->m_pPixels, NULL, 0);
01262 
01263                         if (!iw->m_hBmp)
01264                         {
01265                                 MessageBox(NULL, "Couldn't create DIB." , "ERROR", MB_OK | MB_ICONEXCLAMATION);
01266                         }
01267                         
01268                         iw->m_hBmpOld = (HBITMAP)SelectObject(iw->m_hDCMem, iw->m_hBmp);
01269 
01270                         if (!iw->m_hBmpOld)
01271                         {
01272                                 MessageBox(NULL, "Couldn't Select Object." , "ERROR", MB_OK | MB_ICONEXCLAMATION);
01273                         }
01274 
01275                         iw->m_iWidth = pImage->width;
01276                         iw->m_iHeight = pImage->height;
01277 
01278                         int padding = 4 - (3 * pImage->width) % 4;
01279                         if (padding == 4) padding = 0;
01280                         iw->m_buffer = new unsigned char[( 3 * pImage->width + padding) * pImage->height];
01281                 }
01282 
01283                 // upload the image into the DIB section
01284                 const int width = pImage->width;
01285                 const int height = pImage->height;
01286                 int padding = 4 - (3 * width) % 4;
01287                 if (padding == 4) padding = 0;
01288                 
01289                 if (pImage->type == CByteImage::eGrayScale)
01290                 {
01291                         const int out_offset = 6 * width + padding;
01292 
01293                         unsigned char *out = iw->m_buffer + (3 * width + padding) * (height - 1);
01294                         unsigned char *in = pImage->pixels;
01295 
01296                         for (int y = 0; y < height; y++, out -= out_offset)
01297                         {
01298                                 for (int x = 0; x < width; x++, out += 3, in++)
01299                                 {
01300                                         const unsigned int c = *in;
01301                                         out[0] = c;
01302                                         out[1] = c;
01303                                         out[2] = c;
01304                                 }
01305                         }
01306                 }
01307                 else
01308                 {
01309                         const int out_offset = 6 * width + padding;
01310 
01311                         unsigned char *out = iw->m_buffer + (3 * width + padding) * (height - 1);
01312                         unsigned char *in = pImage->pixels;
01313 
01314                         for (int y = 0; y < height; y++, out -= out_offset)
01315                         {
01316                                 for (int x = 0; x < width; x++, out += 3, in += 3)
01317                                 {
01318                                         out[0] = in[2];
01319                                         out[1] = in[1];
01320                                         out[2] = in[0];
01321                                 }
01322                         }
01323                 }
01324 
01325                 memcpy(iw->m_pPixels, iw->m_buffer, (3 * width + padding) * height);
01326 
01327                 // tell the window it has to redraw the area
01328                 InvalidateRect(iw->m_hWnd, NULL, false);
01329 
01330                 return true;
01331         }
01332 
01333         return false;
01334 }
01335 
01336 bool CWin32MainWindow::GetValue(WIDGET_HANDLE widget, int &value)
01337 {
01338         Win32Widget *w = (Win32Widget*)widget;
01339 
01340         if (w->m_eType == eCheckBox)
01341         {
01342                 BOOL checked = IsDlgButtonChecked(m_hWnd, w->m_index+1);
01343 
01344                 value = (checked ? 1 : 0);
01345 
01346                 return true;
01347         }
01348         else if (w->m_eType == eSlider)
01349         {
01350                 value = (int) SendMessage(w->m_hWnd, TBM_GETPOS, 0, 0);
01351 
01352                 return true;
01353         }
01354         else if (w->m_eType == eComboBox)
01355         {
01356                 value = (int) SendMessage(w->m_hWnd, CB_GETCURSEL, 0, 0);
01357 
01358                 return true;
01359         }
01360 
01361         return false;
01362 }
01363 bool CWin32MainWindow::SetValue(WIDGET_HANDLE widget, int value)
01364 {
01365         Win32Widget *w = (Win32Widget*)widget;
01366 
01367         if (w->m_eType == eCheckBox)
01368         {
01369                 if (value != 0)
01370                         CheckDlgButton(m_hWnd, w->m_index+1, BST_CHECKED);
01371                 else
01372                         CheckDlgButton(m_hWnd, w->m_index+1, BST_UNCHECKED);
01373 
01374                 return true;
01375         }
01376         else if (w->m_eType == eSlider)
01377         {
01378                 SendMessage(w->m_hWnd, TBM_SETPOS, TRUE, value);
01379 
01380                 return true;
01381         }
01382         else if (w->m_eType == eComboBox)
01383         {
01384                 SendMessage(w->m_hWnd, CB_SETCURSEL, value, 0);
01385 
01386                 return true;
01387         }
01388 
01389         return false;
01390 }
01391 
01392 bool CWin32MainWindow::SwapBuffersGLWidget(WIDGET_HANDLE widget)
01393 {
01394         Win32Widget *w = (Win32Widget*)widget;
01395 
01396         if (w->m_eType == eGLWidget)
01397         {
01398                 Win32GLWidget *glw = (Win32GLWidget*)w;
01399 
01400                 SwapBuffers(glw->m_hDC);
01401 
01402                 return true;
01403         }
01404 
01405         return false;
01406 }
01407 
01408 bool CWin32MainWindow::MakeCurrentGLWidget(WIDGET_HANDLE widget)
01409 {
01410         Win32Widget *w = (Win32Widget*)widget;
01411 
01412         if (w->m_eType == eGLWidget)
01413         {
01414                 Win32GLWidget *glw = (Win32GLWidget*)w;
01415 
01416                 wglMakeCurrent(glw->m_hDC, glw->m_hGLRC);
01417 
01418                 return true;
01419         }
01420 
01421         return false;
01422 }
01423 
01424 
01425 // window control
01426 void CWin32MainWindow::Show(WIDGET_HANDLE widget)
01427 {
01428         Win32Widget *w = (Win32Widget*)widget;
01429 
01430         if (w == NULL)
01431         {
01432                 ShowWindow(m_hWnd, SW_SHOW);
01433                 InvalidateRect(m_hWnd, NULL, false);
01434         }
01435         else
01436         {
01437                 ShowWindow(w->m_hWnd, SW_SHOW);
01438                 InvalidateRect(w->m_hWnd, NULL, false);
01439         }
01440 }
01441 void CWin32MainWindow::Hide(WIDGET_HANDLE widget)
01442 {
01443         Win32Widget *w = (Win32Widget*)widget;
01444 
01445         if (w == NULL)
01446         {
01447                 ShowWindow(m_hWnd, SW_HIDE);
01448         }
01449         else
01450         {
01451                 ShowWindow(w->m_hWnd, SW_HIDE);
01452         }
01453 }
01454 
01455 void CWin32MainWindow::SetSize(int width, int height, WIDGET_HANDLE widget)
01456 {
01457         Win32Widget *w = (Win32Widget *) widget;
01458 
01459         if (w)
01460         {
01461                 SetWindowPos(w->m_hWnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE);
01462         }
01463         else
01464         {
01465                 SetWindowPos(m_hWnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE);
01466         }
01467 }
01468 
01469 int CWin32MainWindow::GetModifierKeyState()
01470 {
01471         int result = 0;
01472         
01473         result |= GetAsyncKeyState(VK_SHIFT) < 0 ? IVT_SHIFT_KEY : 0;
01474     result |= GetAsyncKeyState(VK_MENU) < 0 ? IVT_ALT_KEY : 0;
01475     result |= GetAsyncKeyState(VK_CONTROL) < 0 ? IVT_CONTROL_KEY : 0;
01476         
01477     return result;
01478 }
01479 
01480 Win32Widget *CWin32MainWindow::FindWidget(HWND handle)
01481 {
01482         int i, c = (int) m_widgets.size();
01483 
01484         for (i = 0; i < c; i++)
01485         {
01486                 Win32Widget *w = m_widgets[i];
01487 
01488                 if (w->m_hWnd == handle)
01489                         return w;
01490         }
01491 
01492         return NULL;
01493 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:58