Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlWin32/Win32Window.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlWin32/Win32Window.hpp>
00033 #include <vlCore/Time.hpp>
00034 #include <shellapi.h>
00035 
00036 using namespace vl;
00037 using namespace vlWin32;
00038 
00039 //-----------------------------------------------------------------------------
00040 namespace vlWin32
00041 {
00042   const wchar_t* gWin32WindowClassName = L"VisualizationLibraryWindowClass";
00043 
00044   bool registerClass()
00045   {
00046     static bool class_already_registered = false;
00047     if (!class_already_registered)
00048     {
00049       WNDCLASS wc;
00050       memset(&wc, 0, sizeof(wc));
00051       /* only register the window class once. */
00052       wc.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
00053       wc.lpfnWndProc   = (WNDPROC)Win32Window::WindowProc;
00054       wc.cbClsExtra    = 0;
00055       wc.cbWndExtra    = 0;
00056       wc.hInstance     = GetModuleHandle(NULL);
00057       wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
00058       wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
00059       wc.hbrBackground = NULL;
00060       wc.lpszMenuName  = NULL;
00061       wc.lpszClassName = gWin32WindowClassName;
00062 
00063       if (!RegisterClass(&wc))
00064         MessageBox(NULL, L"Class registration failed.", L"Visualization Library Error", MB_OK);
00065       else
00066         class_already_registered = true;
00067     }
00068     return class_already_registered;
00069   }
00070 
00071   #if 0
00072     // used for debugging purposes
00073     void win32PrintError(LPTSTR lpszFunction) 
00074     { 
00075         TCHAR szBuf[80]; 
00076         LPVOID lpMsgBuf;
00077         DWORD dw = GetLastError(); 
00078 
00079         FormatMessage(
00080             FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00081             FORMAT_MESSAGE_FROM_SYSTEM,
00082             NULL,
00083             dw,
00084             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00085             (LPTSTR) &lpMsgBuf,
00086             0, NULL );
00087 
00088         wsprintf(szBuf, 
00089             L"%s failed with error %d: %s", 
00090             lpszFunction, dw, lpMsgBuf); 
00091      
00092         MessageBox(NULL, szBuf, L"Visualization Library Error", MB_OK); 
00093 
00094         LocalFree(lpMsgBuf);
00095     }
00096   #endif
00097 }
00098 //-----------------------------------------------------------------------------
00099 std::map< HWND, Win32Window* > Win32Window::mWinMap;
00100 //-----------------------------------------------------------------------------
00101 LONG WINAPI Win32Window::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00102 { 
00103   Win32Window* win = Win32Window::getWindow(hWnd);
00104   if (!win)
00105     return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00106 
00107   switch(uMsg) 
00108   {
00109     case WM_PAINT:
00110     {
00111       // handle event and then dispatch: solves MessageBox dialog problem.
00112       LONG val = (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00113       if (win->hglrc() && win->hdc() && win->hwnd())
00114         win->dispatchRunEvent();
00115       return val;
00116     }
00117 
00118     case WM_SIZE:
00119     {
00120       win->framebuffer()->setWidth( LOWORD(lParam) );
00121       win->framebuffer()->setHeight( HIWORD(lParam) );
00122       win->dispatchResizeEvent( LOWORD(lParam), HIWORD(lParam) );
00123       break;
00124     }
00125 
00126     case WM_MOUSEMOVE:
00127     {
00128       POINTS pt = MAKEPOINTS(lParam);
00129       win->dispatchMouseMoveEvent( pt.x, pt.y );
00130       break;
00131     }
00132 
00133     case WM_LBUTTONDBLCLK:
00134     case WM_LBUTTONDOWN:
00135     case WM_MBUTTONDBLCLK:
00136     case WM_MBUTTONDOWN:
00137     case WM_RBUTTONDBLCLK:
00138     case WM_RBUTTONDOWN:
00139     {
00140       win->mMouseDownCount++;
00141       if (win->mMouseDownCount == 1)
00142         SetCapture(win->hwnd());
00143       EMouseButton button = UnknownButton;
00144       if (uMsg == WM_LBUTTONDBLCLK || uMsg == WM_LBUTTONDOWN)
00145         button = LeftButton;
00146       else if (uMsg == WM_MBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN)
00147         button = MiddleButton;
00148       else if (uMsg == WM_RBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN)
00149         button = RightButton;
00150       POINTS pt = MAKEPOINTS(lParam);
00151       win->dispatchMouseDownEvent( button, pt.x, pt.y );
00152       break;
00153     }
00154 
00155     case WM_LBUTTONUP:
00156     case WM_RBUTTONUP:
00157     case WM_MBUTTONUP:
00158     {
00159       win->mMouseDownCount--;
00160       if (win->mMouseDownCount <= 0)
00161       {
00162         ReleaseCapture();
00163         win->mMouseDownCount = 0;
00164       }
00165       EMouseButton button = UnknownButton;
00166       if (uMsg == WM_LBUTTONUP)
00167         button = LeftButton;
00168       else if (uMsg == WM_MBUTTONUP)
00169         button = MiddleButton;
00170       else if (uMsg == WM_RBUTTONUP)
00171         button = RightButton;
00172       POINTS pt = MAKEPOINTS(lParam);
00173       win->dispatchMouseUpEvent( button, pt.x, pt.y );
00174       break;
00175     }
00176 
00177     // If you get a compilation error here:
00178     // 1 - you didn't define _WIN32_WINNT as 0x0400 or above.
00179     // 2 - you are trying to compile VL with a VERY old (unsupported) Visual Studio / Platform SDK.
00180     case WM_MOUSEWHEEL:
00181     {
00182       win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
00183       break;
00184     }
00185 
00186     /*case WM_CLOSE:
00187     {
00188       win->dispatchDestroyEvent();
00189       win->destroyWin32GLWindow();
00190       break;
00191     }*/
00192 
00193     case WM_DESTROY:
00194     {
00195       Win32Window::mWinMap.erase(hWnd);
00196       win->dispatchDestroyEvent();
00197       win->destroyWin32GLWindow();
00198       break;
00199     }
00200 
00201     case WM_KEYDOWN:
00202     {
00203       unsigned short unicode_out = 0;
00204       vl::EKey       key_out     = Key_None;
00205       translateKeyEvent(wParam, lParam, unicode_out, key_out);
00206       win->dispatchKeyPressEvent(unicode_out, key_out);
00207       break;
00208     }
00209 
00210     case WM_KEYUP:
00211     {
00212       unsigned short unicode_out = 0;
00213       vl::EKey       key_out     = Key_None;
00214       translateKeyEvent(wParam, lParam, unicode_out, key_out);
00215       win->dispatchKeyReleaseEvent(unicode_out, key_out);
00216       break;
00217     }
00218 
00219     case WM_DROPFILES:
00220     {
00221       HDROP hDrop = (HDROP)wParam;
00222       int count = DragQueryFile(hDrop, 0xFFFFFFFF, 0, 0);
00223       const int char_count = 1024;
00224       std::vector<String> files;
00225       for(int i=0; i<count; ++i)
00226       {
00227         wchar_t file_path[char_count];
00228         memset(file_path, 0, char_count);
00229         DragQueryFile(hDrop,i,file_path,char_count);
00230         files.push_back(file_path);
00231       }
00232       win->dispatchFileDroppedEvent(files);
00233       break;
00234     }
00235 
00236     // WM_SYSKEYDOWN
00237     // WM_SYSKEYUP
00238     // WM_GETICON
00239     // WM_SETCURSOR
00240     // WM_SETICON
00241     // WM_CAPTURECHANGED
00242     // WM_MOUSEFIRST 
00243   }
00244 
00245   return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00246 }
00247 //-----------------------------------------------------------------------------
00248 // Win32Window
00249 //-----------------------------------------------------------------------------
00250 Win32Window::Win32Window()
00251 {
00252   mHWND  = NULL;
00253   mHDC   = NULL;
00254   mHGLRC = NULL;
00255   mMouseDownCount = 0;
00256 
00257   mStyle   = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
00258   mExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
00259   mWindowClassName = gWin32WindowClassName;
00260 }
00261 //-----------------------------------------------------------------------------
00262 Win32Window::~Win32Window()
00263 {
00264   destroyWin32GLWindow();
00265 }
00266 //-----------------------------------------------------------------------------
00267 bool Win32Window::initWin32GLWindow(HWND parent, HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
00268 {
00269   destroyWin32GLWindow();
00270 
00271   if (!registerClass())
00272     return false;
00273 
00274   unsigned style = mStyle & ~(WS_CHILD|WS_OVERLAPPEDWINDOW);;
00275   style |= parent?WS_CHILD:WS_OVERLAPPEDWINDOW;
00276 
00277   mHWND = CreateWindowEx(
00278     mExStyle,
00279     mWindowClassName,
00280     L"Visualization Library Win32",
00281     style,
00282     x, y, width, height, 
00283     parent, NULL, GetModuleHandle(NULL), NULL);
00284 
00285   if (initWin32GLContext(share_context, title, fmt, x, y, width, height))
00286   {
00287     mWinMap[mHWND] = this;
00288     return true;
00289   }
00290   else
00291     return false;
00292 }
00293 //-----------------------------------------------------------------------------
00294 Win32Window* Win32Window::getWindow(HWND hWnd)
00295 {
00296   std::map< HWND, Win32Window* >::const_iterator it = mWinMap.find(hWnd);
00297   if (it != mWinMap.end())
00298     return it->second;
00299   else 
00300     return NULL;
00301 }
00302 //-----------------------------------------------------------------------------
00303 void Win32Window::destroyWin32GLWindow()
00304 {
00305   // wglMakeCurrent(NULL, NULL) not needed 
00306 
00307   if (hwnd())
00308   {
00309     bool destroy_win = mWinMap.find(mHWND) != mWinMap.end();
00310 
00311     // WM_DESTROY must be dispatched while the OpenGL context is still available!
00312     if (destroy_win)
00313     {
00314       DestroyWindow(mHWND);
00315       mHWND = NULL;
00316     }
00317     if (mHGLRC)
00318     {
00319       if ( wglDeleteContext(mHGLRC) == FALSE )
00320       {
00321         MessageBox(NULL, L"OpenGL context creation failed.\n"
00322          L"The handle either doesn't specify a valid context or the context is being used by another thread.", L"Visualization Library Error", MB_OK);
00323       }
00324       mHGLRC = NULL;
00325     }
00326     if (mHDC)
00327     {
00328       DeleteDC(mHDC);
00329       mHDC = NULL;
00330     }
00331   }
00332 }
00333 //-----------------------------------------------------------------------------
00334 void vlWin32::dispatchUpdate()
00335 {
00336   // iterate over all opengl contexts
00337   std::map< HWND, Win32Window* > wins = Win32Window::winMap();
00338   for( std::map< HWND, Win32Window* >::iterator it = wins.begin();
00339        it != wins.end(); 
00340        ++it )
00341   {
00342     Win32Window* win = it->second;
00343     if ( win->continuousUpdate() )
00344       win->update();
00345     else
00346       Sleep(10);
00347   }
00348 }
00349 //-----------------------------------------------------------------------------
00350 void vlWin32::peekMessage(MSG& msg)
00351 {
00352   if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
00353   {
00354     if (msg.message != WM_QUIT)
00355     {
00356       TranslateMessage(&msg);
00357       DispatchMessage(&msg);
00358     }
00359   }
00360   else
00361     dispatchUpdate();
00362 }
00363 //-----------------------------------------------------------------------------
00364 int vlWin32::messageLoop()
00365 {
00366   while(!Win32Window::winMap().empty())
00367   {
00368     MSG msg = {0,0,0,0,0,0,0};
00369     peekMessage(msg);
00370     if (msg.message == WM_QUIT)
00371       return (int)msg.wParam;
00372   }
00373   return 0; /* never reached */
00374 }
00375 //-----------------------------------------------------------------------------
00376 void vlWin32::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
00377 {
00378   // translate non unicode characters
00379   key_out     = Key_None;
00380   unicode_out = 0;
00381 
00382   switch(wParam)
00383   {
00384     case VK_CLEAR:    key_out = Key_Clear; break;
00385     case VK_CONTROL:  key_out = Key_Ctrl; break;
00386     case VK_LCONTROL: key_out = Key_LeftCtrl; break;
00387     case VK_RCONTROL: key_out = Key_RightCtrl; break;
00388     case VK_MENU:     key_out = Key_Alt; break;
00389     case VK_LMENU:    key_out = Key_LeftAlt; break;
00390     case VK_RMENU:    key_out = Key_RightAlt; break;
00391     case VK_SHIFT:    key_out = Key_Shift; break;
00392     case VK_LSHIFT:   key_out = Key_LeftShift; break;
00393     case VK_RSHIFT:   key_out = Key_RightShift; break;
00394     case VK_INSERT:   key_out = Key_Insert; break;
00395     case VK_DELETE:   key_out = Key_Delete; break;
00396     case VK_HOME:     key_out = Key_Home; break;
00397     case VK_END:      key_out = Key_End; break;
00398     case VK_PRINT:    key_out = Key_Print; break;
00399     case VK_PAUSE:    key_out = Key_Pause; break;
00400     case VK_PRIOR:    key_out = Key_PageUp; break;
00401     case VK_NEXT:     key_out = Key_PageDown; break;
00402     case VK_LEFT:     key_out = Key_Left; break;
00403     case VK_RIGHT:    key_out = Key_Right; break;
00404     case VK_UP:       key_out = Key_Up; break;
00405     case VK_DOWN:     key_out = Key_Down; break;
00406     case VK_F1:       key_out = Key_F1; break;
00407     case VK_F2:       key_out = Key_F2; break;
00408     case VK_F3:       key_out = Key_F3; break;
00409     case VK_F4:       key_out = Key_F4; break;
00410     case VK_F5:       key_out = Key_F5; break;
00411     case VK_F6:       key_out = Key_F6; break;
00412     case VK_F7:       key_out = Key_F7; break;
00413     case VK_F8:       key_out = Key_F8; break;
00414     case VK_F9:       key_out = Key_F9; break;
00415     case VK_F10:      key_out = Key_F10; break;
00416     case VK_F11:      key_out = Key_F11; break;
00417     case VK_F12:      key_out = Key_F12; break;
00418 
00419     /*
00420      * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
00421      * 0x40 : is unassigned
00422      * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
00423      */
00424 
00425     case L'0': key_out = Key_0; break;
00426     case L'1': key_out = Key_1; break;
00427     case L'2': key_out = Key_2; break;
00428     case L'3': key_out = Key_3; break;
00429     case L'4': key_out = Key_4; break;
00430     case L'5': key_out = Key_5; break;
00431     case L'6': key_out = Key_6; break;
00432     case L'7': key_out = Key_7; break;
00433     case L'8': key_out = Key_8; break;
00434     case L'9': key_out = Key_9; break;
00435 
00436     case L'A': key_out = Key_A; break;
00437     case L'B': key_out = Key_B; break;
00438     case L'C': key_out = Key_C; break;
00439     case L'D': key_out = Key_D; break;
00440     case L'E': key_out = Key_E; break;
00441     case L'F': key_out = Key_F; break;
00442     case L'G': key_out = Key_G; break;
00443     case L'H': key_out = Key_H; break;
00444     case L'I': key_out = Key_I; break;
00445     case L'J': key_out = Key_J; break;
00446     case L'K': key_out = Key_K; break;
00447     case L'L': key_out = Key_L; break;
00448     case L'M': key_out = Key_M; break;
00449     case L'N': key_out = Key_N; break;
00450     case L'O': key_out = Key_O; break;
00451     case L'P': key_out = Key_P; break;
00452     case L'Q': key_out = Key_Q; break;
00453     case L'R': key_out = Key_R; break;
00454     case L'S': key_out = Key_S; break;
00455     case L'T': key_out = Key_T; break;
00456     case L'U': key_out = Key_U; break;
00457     case L'V': key_out = Key_V; break;
00458     case L'W': key_out = Key_W; break;
00459     case L'X': key_out = Key_X; break;
00460     case L'Y': key_out = Key_Y; break;
00461     case L'Z': key_out = Key_Z; break;
00462   }
00463 
00464   // fill unicode
00465   BYTE mskeys[256];
00466   memset( mskeys, 0, sizeof(BYTE)*256 );
00467   WCHAR unicode[4] = { 0, 0 };
00468   if ( ToUnicode( (UINT)wParam, (UINT)((lParam >> 16) & 0xFF), mskeys, unicode, 4, 0 ) == 1 )
00469   {
00470     unicode_out = unicode[0];
00471 
00472     // fill key
00473     switch(unicode_out)
00474     {
00475       case L'0': key_out = Key_0; break;
00476       case L'1': key_out = Key_1; break;
00477       case L'2': key_out = Key_2; break;
00478       case L'3': key_out = Key_3; break;
00479       case L'4': key_out = Key_4; break;
00480       case L'5': key_out = Key_5; break;
00481       case L'6': key_out = Key_6; break;
00482       case L'7': key_out = Key_7; break;
00483       case L'8': key_out = Key_8; break;
00484       case L'9': key_out = Key_9; break;
00485 
00486       case L'A': key_out = Key_A; break;
00487       case L'B': key_out = Key_B; break;
00488       case L'C': key_out = Key_C; break;
00489       case L'D': key_out = Key_D; break;
00490       case L'E': key_out = Key_E; break;
00491       case L'F': key_out = Key_F; break;
00492       case L'G': key_out = Key_G; break;
00493       case L'H': key_out = Key_H; break;
00494       case L'I': key_out = Key_I; break;
00495       case L'J': key_out = Key_J; break;
00496       case L'K': key_out = Key_K; break;
00497       case L'L': key_out = Key_L; break;
00498       case L'M': key_out = Key_M; break;
00499       case L'N': key_out = Key_N; break;
00500       case L'O': key_out = Key_O; break;
00501       case L'P': key_out = Key_P; break;
00502       case L'Q': key_out = Key_Q; break;
00503       case L'R': key_out = Key_R; break;
00504       case L'S': key_out = Key_S; break;
00505       case L'T': key_out = Key_T; break;
00506       case L'U': key_out = Key_U; break;
00507       case L'V': key_out = Key_V; break;
00508       case L'W': key_out = Key_W; break;
00509       case L'X': key_out = Key_X; break;
00510       case L'Y': key_out = Key_Y; break;
00511       case L'Z': key_out = Key_Z; break;
00512 
00513       case L'a': key_out = Key_A; break;
00514       case L'b': key_out = Key_B; break;
00515       case L'c': key_out = Key_C; break;
00516       case L'd': key_out = Key_D; break;
00517       case L'e': key_out = Key_E; break;
00518       case L'f': key_out = Key_F; break;
00519       case L'g': key_out = Key_G; break;
00520       case L'h': key_out = Key_H; break;
00521       case L'i': key_out = Key_I; break;
00522       case L'j': key_out = Key_J; break;
00523       case L'k': key_out = Key_K; break;
00524       case L'l': key_out = Key_L; break;
00525       case L'm': key_out = Key_M; break;
00526       case L'n': key_out = Key_N; break;
00527       case L'o': key_out = Key_O; break;
00528       case L'p': key_out = Key_P; break;
00529       case L'q': key_out = Key_Q; break;
00530       case L'r': key_out = Key_R; break;
00531       case L's': key_out = Key_S; break;
00532       case L't': key_out = Key_T; break;
00533       case L'u': key_out = Key_U; break;
00534       case L'v': key_out = Key_V; break;
00535       case L'w': key_out = Key_W; break;
00536       case L'x': key_out = Key_X; break;
00537       case L'y': key_out = Key_Y; break;
00538       case L'z': key_out = Key_Z; break;
00539 
00540       case 13: key_out = Key_Return; break;
00541       case 8: key_out = Key_BackSpace; break;
00542       case 9: key_out = Key_Tab; break;
00543       case L' ': key_out = Key_Space; break;
00544 
00545       case 27: key_out = Key_Escape; break;
00546       case L'!': key_out = Key_Exclam; break;
00547       case L'"': key_out = Key_QuoteDbl; break;
00548       case L'#': key_out = Key_Hash; break;
00549       case L'$': key_out = Key_Dollar; break;
00550       case L'&': key_out = Key_Ampersand; break;
00551       case L'\'': key_out = Key_Quote; break;
00552       case L'(': key_out = Key_LeftParen; break;
00553       case L')': key_out = Key_RightParen; break;
00554       case L'*': key_out = Key_Asterisk; break;
00555       case L'+': key_out = Key_Plus; break;
00556       case L',': key_out = Key_Comma; break;
00557       case L'-': key_out = Key_Minus; break;
00558       case L'.': key_out = Key_Period; break;
00559       case L'\\': key_out = Key_Slash; break;
00560       case L':': key_out = Key_Colon; break;
00561       case L';': key_out = Key_Semicolon; break;
00562       case L'<': key_out = Key_Less; break;
00563       case L'=': key_out = Key_Equal; break;
00564       case L'>': key_out = Key_Greater; break;
00565       case L'?': key_out = Key_Question; break;
00566       case L'@': key_out = Key_At; break;
00567       case L'[': key_out = Key_LeftBracket; break;
00568       case L'/': key_out = Key_BackSlash; break;
00569       case L']': key_out = Key_RightBracket; break;
00570       case L'|': key_out = Key_Caret; break;
00571       case L'_': key_out = Key_Underscore; break;
00572       case L'`': key_out = Key_QuoteLeft; break;
00573     }
00574   }
00575 }
00576 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:44.
Permission is granted to use this page to write and publish articles regarding Visualization Library.