Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

wintrack.cpp

Go to the documentation of this file.
00001 /*
00002  * Window tracking related functions.
00003  *
00004  * Copyright 2001 Sander van Leeuwen
00005  *
00006  * Changes from Wine code: (20011004)
00007  * - Only draw changed track frame instead of clearing the old one and
00008  *   drawing the new one (less flickering)
00009  * - Send WM_MOVING when moving a window (not done in Wine)
00010  * - Send WM_SIZING only when sizing a window 
00011  * - Fixed handling of rectangles changed by WM_SIZING/MOVING
00012  *
00013  * Based on Wine code: (dlls\x11drv\winpos.c)
00014  *
00015  * Copyright 1993, 1994, 1995, 2001 Alexandre Julliard
00016  * Copyright 1995, 1996, 1999 Alex Korobka
00017  *
00018  */
00019 #include <os2win.h>
00020 #include <string.h>
00021 
00022 #include "win32wbase.h"
00023 #include "hook.h"
00024 #include "pmwindow.h"
00025 
00026 #define ON_LEFT_BORDER(hit) \
00027  (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
00028 #define ON_RIGHT_BORDER(hit) \
00029  (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
00030 #define ON_TOP_BORDER(hit) \
00031  (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
00032 #define ON_BOTTOM_BORDER(hit) \
00033  (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
00034 
00035 #define RECT_WIDTH(a)   ((a)->right - (a)->left)
00036 #define RECT_HEIGHT(a)  ((a)->bottom - (a)->top) 
00037 #define RECT_EQUAL(a,b) (memcmp(a, b, sizeof(RECT)) == 0)
00038 
00039 #ifdef CUSTOM_TRACKFRAME 
00040 
00041 /***********************************************************************
00042  *           draw_moving_frame
00043  *
00044  * Draw the frame used when moving or resizing window.
00045  *
00046  * FIXME:  This causes problems in Win95 mode.  (why?)
00047  */
00048 static void draw_moving_frame( HDC hdc, RECT *rect, BOOL thickframe, DWORD hittest, BOOL fRedraw)
00049 {
00050     if (thickframe)
00051     {
00052         const int width = GetSystemMetrics(SM_CXFRAME);
00053         const int height = GetSystemMetrics(SM_CYFRAME);
00054 
00055         static RECT oldRect = {0};
00056 
00057         if(fRedraw && EqualRect(&oldRect, rect)) {
00058             return;
00059         }
00060 
00061         HBRUSH hbrush = SelectObject( hdc, GetStockObject( GRAY_BRUSH ) );
00062         if(fRedraw && hittest != HTCAPTION) 
00063         {
00064              int x, y, linewidth, lineheight;
00065 
00066              //This should be done in a better way (less code), but at least
00067              //it works.
00068              switch(hittest) {
00069              case HTLEFT:
00070                  //clear old edge
00071                  PatBlt( hdc, oldRect.left, oldRect.top + height,
00072                          width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00073                  //and draw new one
00074                  PatBlt( hdc, rect->left, rect->top + height,
00075                          width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00076 
00077                  if(oldRect.left > rect->left) {
00078                      x = rect->left;
00079                      linewidth = oldRect.left - rect->left;
00080                  }
00081                  else {
00082                      x = oldRect.left;
00083                      linewidth = rect->left - oldRect.left;
00084                  }
00085                  PatBlt(hdc, x, oldRect.top,      linewidth, height,  PATINVERT);
00086                  PatBlt(hdc, x, oldRect.bottom-1, linewidth, -height, PATINVERT);
00087                  break;
00088              case HTRIGHT:
00089                  //clear old edge
00090                  PatBlt( hdc, oldRect.right-1, oldRect.top + height,
00091                          -width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00092                  //and draw new one
00093                  PatBlt( hdc, rect->right-1, rect->top + height,
00094                          -width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00095 
00096                  if(oldRect.right > rect->right) {
00097                      x = rect->right;
00098                      linewidth = oldRect.right - rect->right;
00099                  }
00100                  else {
00101                      x = oldRect.right;
00102                      linewidth = rect->right - oldRect.right;
00103                  }
00104                  PatBlt( hdc, x, oldRect.top,      linewidth,  height, PATINVERT );
00105                  PatBlt( hdc, x, oldRect.bottom-1, linewidth, -height, PATINVERT );
00106                  break;
00107 
00108              case HTTOP:
00109                  //clear old edge
00110                  PatBlt( hdc, oldRect.left + width, oldRect.top,
00111                          RECT_WIDTH(&oldRect) - 2*width, height, PATINVERT );
00112                  //and draw new one
00113                  PatBlt( hdc, rect->left + width, rect->top,
00114                          RECT_WIDTH(rect) - 2*width, height, PATINVERT );
00115 
00116                  if(oldRect.top > rect->top) {
00117                      y = rect->top;
00118                      lineheight = oldRect.top - rect->top;
00119                  }
00120                  else {
00121                      y = oldRect.top;
00122                      lineheight = rect->top - oldRect.top;
00123                  }
00124 
00125                  PatBlt( hdc, oldRect.left,      y,  width, lineheight, PATINVERT );
00126                  PatBlt( hdc, oldRect.right - 1, y, -width, lineheight, PATINVERT );
00127                  break;
00128 
00129              case HTBOTTOM:
00130                  //clear old edge
00131                  PatBlt( hdc, oldRect.left + width, oldRect.bottom-1,
00132                          RECT_WIDTH(&oldRect) - 2*width, -height, PATINVERT );
00133                  //and draw new one
00134                  PatBlt( hdc, rect->left + width, rect->bottom-1,
00135                          RECT_WIDTH(rect) - 2*width, -height, PATINVERT );
00136 
00137                  if(oldRect.bottom > rect->bottom) {
00138                      y = rect->bottom;
00139                      lineheight = oldRect.bottom - rect->bottom;
00140                  }
00141                  else {
00142                      y = oldRect.bottom;
00143                      lineheight = rect->bottom - oldRect.bottom;
00144                  }
00145 
00146                  PatBlt( hdc, oldRect.left,      y,  width, lineheight, PATINVERT );
00147                  PatBlt( hdc, oldRect.right - 1, y, -width, lineheight, PATINVERT );
00148                  break;
00149 
00150              case HTBOTTOMLEFT:
00151                  //clear old edge (bottom)
00152                  PatBlt( hdc, oldRect.left, oldRect.bottom-1,
00153                          RECT_WIDTH(&oldRect) - width, -height, PATINVERT );
00154                  //and draw new one
00155                  PatBlt( hdc, rect->left, rect->bottom-1,
00156                          RECT_WIDTH(rect) - width, -height, PATINVERT );
00157 
00158                  //clear old edge (left)
00159                  PatBlt( hdc, oldRect.left, oldRect.top + height,
00160                          width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00161                  //and draw new one
00162                  PatBlt( hdc, rect->left, rect->top + height,
00163                          width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00164 
00165                  //right
00166                  if(oldRect.bottom > rect->bottom) {
00167                      y = rect->bottom;
00168                      lineheight = oldRect.bottom - rect->bottom;
00169                  }
00170                  else {
00171                      y = oldRect.bottom;
00172                      lineheight = rect->bottom - oldRect.bottom;
00173                  }
00174                  PatBlt( hdc, oldRect.right-1, y,  -width, lineheight, PATINVERT );
00175 
00176                  //top
00177                  if(oldRect.left > rect->left) {
00178                      x = rect->left;
00179                      linewidth = oldRect.left - rect->left;
00180                  }
00181                  else {
00182                      x = oldRect.left;
00183                      linewidth = rect->left - oldRect.left;
00184                  }
00185                  PatBlt(hdc, x, oldRect.top, linewidth, height,  PATINVERT);
00186                  break;
00187 
00188              case HTBOTTOMRIGHT:
00189                  //clear old edge (bottom)
00190                  PatBlt( hdc, oldRect.left + width, oldRect.bottom-1,
00191                          RECT_WIDTH(&oldRect) - width, -height, PATINVERT );
00192                  //and draw new one
00193                  PatBlt( hdc, rect->left + width, rect->bottom-1,
00194                          RECT_WIDTH(rect) - width, -height, PATINVERT );
00195 
00196                  //clear old edge (right)
00197                  PatBlt( hdc, oldRect.right-1, oldRect.top + height,
00198                          -width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00199                  //and draw new one
00200                  PatBlt( hdc, rect->right-1, rect->top + height,
00201                          -width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00202 
00203                  //left
00204                  if(oldRect.bottom > rect->bottom) {
00205                      y = rect->bottom;
00206                      lineheight = oldRect.bottom - rect->bottom;
00207                  }
00208                  else {
00209                      y = oldRect.bottom;
00210                      lineheight = rect->bottom - oldRect.bottom;
00211                  }
00212                  PatBlt( hdc, oldRect.left, y, width, lineheight, PATINVERT );
00213 
00214                  //top
00215                  if(oldRect.right > rect->right) {
00216                      x = rect->right;
00217                      linewidth = oldRect.right - rect->right;
00218                  }
00219                  else {
00220                      x = oldRect.right;
00221                      linewidth = rect->right - oldRect.right;
00222                  }
00223                  PatBlt(hdc, x, oldRect.top, linewidth, height,  PATINVERT);
00224                  break;
00225 
00226              case HTTOPLEFT:
00227                  //clear old edge (top)
00228                  PatBlt( hdc, oldRect.left, oldRect.top,
00229                          RECT_WIDTH(&oldRect) - width, height, PATINVERT );
00230                  //and draw new one
00231                  PatBlt( hdc, rect->left, rect->top,
00232                          RECT_WIDTH(rect) - width, height, PATINVERT );
00233 
00234                  //clear old edge (left)
00235                  PatBlt( hdc, oldRect.left, oldRect.top + height,
00236                          width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00237                  //and draw new one
00238                  PatBlt( hdc, rect->left, rect->top + height,
00239                          width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00240 
00241                  //right
00242                  if(oldRect.top > rect->top) {
00243                      y = rect->top;
00244                      lineheight = oldRect.top - rect->top;
00245                  }
00246                  else {
00247                      y = oldRect.top;
00248                      lineheight = rect->top - oldRect.top;
00249                  }
00250                  PatBlt( hdc, oldRect.right-1, y,  -width, lineheight, PATINVERT );
00251 
00252                  //bottom
00253                  if(oldRect.left > rect->left) {
00254                      x = rect->left;
00255                      linewidth = oldRect.left - rect->left;
00256                  }
00257                  else {
00258                      x = oldRect.left;
00259                      linewidth = rect->left - oldRect.left;
00260                  }
00261                  PatBlt(hdc, x, oldRect.bottom-1, linewidth, -height,  PATINVERT);
00262                  break;
00263 
00264              case HTTOPRIGHT:
00265                  //clear old edge (top)
00266                  PatBlt( hdc, oldRect.left+width, oldRect.top,
00267                          RECT_WIDTH(&oldRect) - width, height, PATINVERT );
00268                  //and draw new one
00269                  PatBlt( hdc, rect->left+width, rect->top,
00270                          RECT_WIDTH(rect) - width, height, PATINVERT );
00271 
00272                  //clear old edge (right)
00273                  PatBlt( hdc, oldRect.right-1, oldRect.top + height,
00274                          -width, RECT_HEIGHT(&oldRect) - 2*height, PATINVERT );
00275                  //and draw new one
00276                  PatBlt( hdc, rect->right-1, rect->top + height,
00277                          -width, RECT_HEIGHT(rect) - 2*height, PATINVERT );
00278 
00279                  //left
00280                  if(oldRect.top > rect->top) {
00281                      y = rect->top;
00282                      lineheight = oldRect.top - rect->top;
00283                  }
00284                  else {
00285                      y = oldRect.top;
00286                      lineheight = rect->top - oldRect.top;
00287                  }
00288                  PatBlt( hdc, oldRect.left, y,  width, lineheight, PATINVERT);
00289 
00290                  //bottom
00291                  if(oldRect.right > rect->right) {
00292                      x = rect->right;
00293                      linewidth = oldRect.right - rect->right;
00294                  }
00295                  else {
00296                      x = oldRect.right;
00297                      linewidth = rect->right - oldRect.right;
00298                  }
00299                  PatBlt(hdc, x, oldRect.bottom-1, linewidth, -height,  PATINVERT);
00300                  break;
00301              }
00302              oldRect = *rect;
00303         }
00304         else { 
00305              if(fRedraw) {
00306                  PatBlt( hdc, oldRect.left, oldRect.top,
00307                          RECT_WIDTH(&oldRect) - width, height, PATINVERT );
00308                  PatBlt( hdc, oldRect.left, oldRect.top + height, width,
00309                          RECT_HEIGHT(&oldRect) - height, PATINVERT );
00310                  PatBlt( hdc, oldRect.left + width, oldRect.bottom - 1,
00311                          RECT_WIDTH(&oldRect) - width, -height, PATINVERT );
00312                  PatBlt( hdc, oldRect.right - 1, oldRect.top, -width,
00313                          RECT_HEIGHT(&oldRect) - height, PATINVERT );
00314              }
00315              oldRect = *rect;
00316              PatBlt( hdc, rect->left, rect->top,
00317                      rect->right - rect->left - width, height, PATINVERT );
00318              PatBlt( hdc, rect->left, rect->top + height, width,
00319                      rect->bottom - rect->top - height, PATINVERT );
00320              PatBlt( hdc, rect->left + width, rect->bottom - 1,
00321                      rect->right - rect->left - width, -height, PATINVERT );
00322              PatBlt( hdc, rect->right - 1, rect->top, -width,
00323                      rect->bottom - rect->top - height, PATINVERT );
00324         }
00325         SelectObject( hdc, hbrush );
00326     }
00327     else {
00328         static RECT oldRect = {0};
00329 
00330         if(fRedraw && EqualRect(&oldRect, rect)) {
00331             return;
00332         }
00333 
00334         if(fRedraw) {
00335             DrawFocusRect( hdc, &oldRect );
00336         }
00337         DrawFocusRect( hdc, rect );
00338         oldRect = *rect;
00339     }
00340 }
00341 
00342 
00343 /***********************************************************************
00344  *           start_size_move
00345  *
00346  * Initialisation of a move or resize, when initiatied from a menu choice.
00347  * Return hit test code for caption or sizing border.
00348  */
00349 static LONG start_size_move( Win32BaseWindow *win32wnd, WPARAM wParam, POINT *capturePoint, LONG style )
00350 {
00351     HWND hwnd = win32wnd->getWindowHandle();
00352     LONG hittest = 0;
00353     POINT pt;
00354     MSG msg;
00355     RECT rectWindow;
00356 
00357     GetWindowRect( hwnd, &rectWindow );
00358 
00359     if ((wParam & 0xfff0) == SC_MOVE)
00360     {
00361         /* Move pointer at the center of the caption */
00362         RECT rect;
00363         win32wnd->GetInsideRect( &rect );
00364         if (style & WS_SYSMENU)
00365             rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
00366         if (style & WS_MINIMIZEBOX)
00367             rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
00368         if (style & WS_MAXIMIZEBOX)
00369             rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
00370         pt.x = rectWindow.left + (rect.right - rect.left) / 2;
00371         pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
00372         hittest = HTCAPTION;
00373         *capturePoint = pt;
00374     }
00375     else  /* SC_SIZE */
00376     {
00377         while(!hittest)
00378         {
00379 //            GetMessageW( &msg, 0, WM_KEYFIRST, WM_MOUSELAST );
00380             GetMessageW( &msg, 0, 0, 0 );
00381             if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
00382 
00383             switch(msg.message)
00384             {
00385             case WM_MOUSEMOVE:
00386                 hittest = win32wnd->HandleNCHitTest( msg.pt );
00387 //                hittest = NC_HandleNCHitTest( hwnd, msg.pt );
00388                 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
00389                     hittest = 0;
00390                 break;
00391 
00392             case WM_LBUTTONUP:
00393                 return 0;
00394 
00395             case WM_KEYDOWN:
00396                 switch(msg.wParam)
00397                 {
00398                 case VK_UP:
00399                     hittest = HTTOP;
00400                     pt.x =(rectWindow.left+rectWindow.right)/2;
00401                     pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
00402                     break;
00403                 case VK_DOWN:
00404                     hittest = HTBOTTOM;
00405                     pt.x =(rectWindow.left+rectWindow.right)/2;
00406                     pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
00407                     break;
00408                 case VK_LEFT:
00409                     hittest = HTLEFT;
00410                     pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
00411                     pt.y =(rectWindow.top+rectWindow.bottom)/2;
00412                     break;
00413                 case VK_RIGHT:
00414                     hittest = HTRIGHT;
00415                     pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
00416                     pt.y =(rectWindow.top+rectWindow.bottom)/2;
00417                     break;
00418                 case VK_RETURN:
00419                 case VK_ESCAPE: return 0;
00420                 }
00421             }
00422         }
00423         *capturePoint = pt;
00424     }
00425     SetCursorPos( pt.x, pt.y );
00426     win32wnd->DefWindowProcA(WM_SETCURSOR, (WPARAM)hwnd, MAKELONG( hittest, WM_MOUSEMOVE ));
00427 //    NC_HandleSetCursor( hwnd, (WPARAM)hwnd, MAKELONG( hittest, WM_MOUSEMOVE ));
00428     dprintf(("start_size_move: hittest %d", hittest));
00429     return hittest;
00430 }
00431 
00432 
00433 /***********************************************************************
00434  *           SysCommandSizeMove   (X11DRV.@)
00435  *
00436  * Perform SC_MOVE and SC_SIZE commands.
00437  */
00438 void Frame_SysCommandSizeMove(Win32BaseWindow *win32wnd, WPARAM wParam )
00439 {
00440     HWND hwnd = win32wnd->getWindowHandle();
00441     MSG msg;
00442     RECT sizingRect, mouseRect, origRect, lastsizingRect;
00443     HDC hdc;
00444     HWND parent;
00445     LONG hittest = (LONG)(wParam & 0x0f);
00446     HCURSOR16 hDragCursor = 0, hOldCursor = 0;
00447     POINT minTrack, maxTrack;
00448     POINT capturePoint, pt;
00449     LONG style = GetWindowLongA( hwnd, GWL_STYLE );
00450     LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
00451     BOOL    thickframe = HAS_THICKFRAME( style, exstyle );
00452     BOOL    iconic = style & WS_MINIMIZE;
00453     BOOL    moved = FALSE;
00454     DWORD     dwPoint = GetMessagePos ();
00455     BOOL DragFullWindows = FALSE;
00456     BOOL fControl = FALSE;
00457     BOOL grab;
00458     int iWndsLocks;
00459 
00460     dprintf(("FrameTrackFrame %x", wParam));
00461 
00462     SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
00463   
00464     pt.x = SLOWORD(dwPoint);
00465     pt.y = SHIWORD(dwPoint);
00466     capturePoint = pt;
00467 
00468 //    if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) || (exstyle & WS_EX_MANAGED)) return;
00469     if (IsZoomed(hwnd) || !IsWindowVisible(hwnd)) return;
00470 
00471     if(fOS2Look) {
00472         fControl = GetAsyncKeyState(VK_CONTROL);
00473         if(DragFullWindows && !fControl) {
00474             //Bring window to top and activate it
00475             SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00476         }
00477     }
00478 
00479     if ((wParam & 0xfff0) == SC_MOVE)
00480     {
00481         if (!hittest) hittest = start_size_move( win32wnd, wParam, &capturePoint, style );
00482         if (!hittest) return;
00483     }
00484     else  /* SC_SIZE */
00485     {
00486         if (!thickframe) return;
00487         if ( hittest && hittest != HTSYSMENU ) hittest += 2;
00488         else
00489         {
00490             SetCapture(hwnd);
00491             hittest = start_size_move( win32wnd, wParam, &capturePoint, style );
00492             if (!hittest)
00493             {
00494                 ReleaseCapture();
00495                 return;
00496             }
00497         }
00498     }
00499 
00500       /* Get min/max info */
00501 
00502 //    WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack );
00503     win32wnd->AdjustTrackInfo(&minTrack, &maxTrack);
00504     GetWindowRect( hwnd, &sizingRect );
00505     if (style & WS_CHILD)
00506     {
00507         parent = GetParent(hwnd);
00508         /* make sizing rect relative to parent */
00509         MapWindowPoints( 0, parent, (POINT*)&sizingRect, 2 );
00510         GetClientRect( parent, &mouseRect );
00511     }
00512     else
00513     {
00514         parent = GetDesktopWindow();
00515         SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
00516     }
00517     origRect = sizingRect;
00518 
00519     if (ON_LEFT_BORDER(hittest))
00520     {
00521         mouseRect.left  = max( mouseRect.left, sizingRect.right-maxTrack.x );
00522         mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
00523     }
00524     else if (ON_RIGHT_BORDER(hittest))
00525     {
00526         mouseRect.left  = max( mouseRect.left, sizingRect.left+minTrack.x );
00527         mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
00528     }
00529     if (ON_TOP_BORDER(hittest))
00530     {
00531         mouseRect.top    = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
00532         mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
00533     }
00534     else if (ON_BOTTOM_BORDER(hittest))
00535     {
00536         mouseRect.top    = max( mouseRect.top, sizingRect.top+minTrack.y );
00537         mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
00538     }
00539     if (parent) MapWindowPoints( parent, 0, (LPPOINT)&mouseRect, 2 );
00540 
00541     /* Retrieve a default cache DC (without using the window style) */
00542     hdc = GetDCEx( parent, 0, DCX_CACHE);
00543 
00544     if( iconic ) /* create a cursor for dragging */
00545     {
00546         HICON hIcon = GetClassLongA( hwnd, GCL_HICON);
00547         if(!hIcon) hIcon = (HICON)SendMessageA( hwnd, WM_QUERYDRAGICON, 0, 0L);
00548         if( hIcon ) hDragCursor = hIcon;
00549 // CURSORICON_IconToCursor( hIcon, TRUE );
00550         if( !hDragCursor ) iconic = FALSE;
00551     }
00552 
00553     /* repaint the window before moving it around */
00554     RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
00555 
00556     SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
00557     SetCapture( hwnd );
00558 
00559     //prevent the app from drawing to this window (or its children)    
00560     if(!DragFullWindows) 
00561         LockWindowUpdate(hwnd);
00562 
00563     while(1)
00564     {
00565         int dx = 0, dy = 0;
00566 
00567 //        if (!GetMessageW( &msg, 0, WM_KEYFIRST, WM_MOUSELAST )) break;
00568         if (!GetMessageW( &msg, 0, 0, 0 )) break;
00569         if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
00570 
00571         /* Exit on button-up, Return, or Esc */
00572         if ((msg.message == WM_LBUTTONUP) || (msg.message == WM_RBUTTONUP) ||
00573             ((msg.message == WM_KEYDOWN) &&
00574              ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
00575 
00576         if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE)) {
00577             DispatchMessageA(&msg);
00578             continue;  /* We are not interested in other messages */
00579         }
00580 
00581         pt = msg.pt;
00582 
00583         if (msg.message == WM_KEYDOWN) switch(msg.wParam)
00584         {
00585         case VK_UP:    pt.y -= 8; break;
00586         case VK_DOWN:  pt.y += 8; break;
00587         case VK_LEFT:  pt.x -= 8; break;
00588         case VK_RIGHT: pt.x += 8; break;
00589         }
00590 
00591         pt.x = max( pt.x, mouseRect.left );
00592         pt.x = min( pt.x, mouseRect.right );
00593         pt.y = max( pt.y, mouseRect.top );
00594         pt.y = min( pt.y, mouseRect.bottom );
00595 
00596         dprintf(("mouseRect (%d,%d)(%d,%d)", mouseRect.left, mouseRect.top, mouseRect.right, mouseRect.bottom));
00597         dprintf(("capturePoint (%d,%d)", capturePoint.x, capturePoint.y));
00598         dx = pt.x - capturePoint.x;
00599         dy = pt.y - capturePoint.y;
00600 
00601         if (dx || dy)
00602         {
00603             if( !moved )
00604             {
00605                 moved = TRUE;
00606 
00607                 if( iconic ) /* ok, no system popup tracking */
00608                 {
00609                     hOldCursor = SetCursor(hDragCursor);
00610                     ShowCursor( TRUE );
00611 //                    WINPOS_ShowIconTitle( hwnd, FALSE );
00612                 }
00613                 else if(!DragFullWindows)
00614                     draw_moving_frame( hdc, &sizingRect, thickframe, hittest, FALSE );
00615             }
00616 
00617             if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
00618             else
00619             {
00620                 RECT newRect = sizingRect, tempRect;
00621                 WPARAM wpSizingHit = 0;
00622 
00623                 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
00624 
00625                 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
00626                 else 
00627                 if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
00628 
00629                 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
00630                 else 
00631                 if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
00632 
00633 ////                if(!iconic && !DragFullWindows) draw_moving_frame( hdc, &sizingRect, thickframe, hittest, TRUE);
00634 
00635                 /* determine the hit location */
00636                 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
00637                     wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
00638 
00639                 tempRect = newRect;
00640 
00641                 dprintf(("WM_SIZING rect (%d,%d)(%d,%d)", newRect.left, newRect.top, newRect.right, newRect.bottom));
00642 
00643                 //Although the docs say the app should return TRUE when processing
00644                 //this message, experiments show that NT checks the rectangle
00645                 //regardless of the return value
00646                 if ((wParam & 0xfff0) == SC_MOVE) {
00647                      SendMessageA( hwnd, WM_MOVING, wpSizingHit, (LPARAM)&newRect );
00648                 }
00649                 else SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
00650 
00651                 dprintf(("WM_SIZING rect (%d,%d)(%d,%d)", newRect.left, newRect.top, newRect.right, newRect.bottom));
00652 
00653                 dprintf(("update capture point dx %d dy %d", dx, dy));
00654                 capturePoint   = pt;
00655                 sizingRect     = tempRect;
00656                 lastsizingRect = newRect;
00657 
00658                 if (!iconic)
00659                 {
00660                     if(!DragFullWindows)
00661                         draw_moving_frame( hdc, &newRect, thickframe, hittest, TRUE );
00662                     else {
00663                         /* To avoid any deadlocks, all the locks on the windows
00664                            structures must be suspended before the SetWindowPos */
00665 //                        iWndsLocks = WIN_SuspendWndsLock();
00666                         SetWindowPos( hwnd, 0, newRect.left, newRect.top,
00667                                       newRect.right - newRect.left,
00668                                       newRect.bottom - newRect.top,
00669                                       ((hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ) | 
00670                                       ((fControl) ? (SWP_NOACTIVATE|SWP_NOZORDER) : 0));
00671 //                        WIN_RestoreWndsLock(iWndsLocks);
00672                     }
00673                 }
00674             }
00675         }
00676     }
00677 
00678     //Enable window update
00679     if(!DragFullWindows) 
00680         LockWindowUpdate(NULL);
00681 
00682     ReleaseCapture();
00683     if( iconic )
00684     {
00685         if( moved ) /* restore cursors, show icon title later on */
00686         {
00687             ShowCursor( FALSE );
00688             SetCursor( hOldCursor );
00689         }
00690         DestroyCursor( hDragCursor );
00691     }
00692     else if (moved && !DragFullWindows)
00693         draw_moving_frame( hdc, &lastsizingRect, thickframe, hittest, FALSE);
00694 
00695     ReleaseDC( parent, hdc );
00696 
00697 //    wine_tsx11_lock();
00698 //    XUngrabPointer( display, CurrentTime );
00699 //    if (grab)
00700 //    {
00701 //        XSync( display, False );
00702 //        XUngrabServer( display );
00703 //        XSync( display, False );
00704 //        gdi_display = old_gdi_display;
00705 //    }
00706 //    wine_tsx11_unlock();
00707 
00708     if (HOOK_CallHooksA( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&lastsizingRect )) moved = FALSE;
00709 
00710     SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
00711     SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
00712 
00713     /* window moved or resized */
00714     if (moved)
00715     {
00716         /* To avoid any deadlocks, all the locks on the windows
00717            structures must be suspended before the SetWindowPos */
00718 //        iWndsLocks = WIN_SuspendWndsLock();
00719 
00720         /* if the moving/resizing isn't canceled call SetWindowPos
00721          * with the new position or the new size of the window
00722          */
00723         if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
00724         {
00725             /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
00726             if(!DragFullWindows)
00727                 SetWindowPos( hwnd, 0, lastsizingRect.left, lastsizingRect.top,
00728                               lastsizingRect.right - lastsizingRect.left,
00729                               lastsizingRect.bottom - lastsizingRect.top,
00730                               ((hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ) | 
00731                               ((fControl) ? (SWP_NOACTIVATE|SWP_NOZORDER) : 0));
00732         }
00733         else
00734         { /* restore previous size/position */
00735             //SvL: TODO: should really restore z-order & activation here
00736             if(DragFullWindows)
00737                 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
00738                               origRect.right - origRect.left,
00739                               origRect.bottom - origRect.top,
00740                               ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
00741         }
00742 
00743 //        WIN_RestoreWndsLock(iWndsLocks);
00744     }
00745     else
00746     if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) ) {
00747         //if action wasn't cancelled, ctrl wasn't pressed and we didn't
00748         //activate the window before (!DragFullWindows), then activate
00749         //and bring it to the top now
00750         if(!fControl && !DragFullWindows) {
00751             //Bring window to top and activate it
00752             SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
00753         }
00754     }
00755 
00756     if (IsIconic(hwnd))
00757     {
00758         /* Single click brings up the system menu when iconized */
00759 
00760         if( !moved )
00761         {
00762             if(style & WS_SYSMENU )
00763                 SendMessageA( hwnd, WM_SYSCOMMAND,
00764                               SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
00765         }
00766 //        else WINPOS_ShowIconTitle( hwnd, TRUE );
00767     }
00768 }
00769 
00770 #endif //#ifdef CUSTOM_TRACKFRAME 

Generated on Wed Jan 23 23:17:55 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001