static void Docking_SetSize(HWND hwnd, LPRECT rc, bool query, bool move) { RECT rcMonitor; Docking_GetMonitorRectFromPoint( docked == DOCKED_LEFT && !query ? (LPPOINT)&rc->right : (LPPOINT)rc, &rcMonitor); Docking_AdjustPosition(hwnd, &rcMonitor, rc, query, move); }
static void Docking_GetMonitorRectFromWindow(HWND hWnd, RECT *rc) { POINT ptWindow; GetWindowRect(hWnd, rc); ptWindow.x = rc->left; ptWindow.y = rc->top; Docking_GetMonitorRectFromPoint(ptWindow, rc); }
int Docking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam) { APPBARDATA abd; static int draggingTitle; MSG *msg = (MSG *)wParam; if (msg->message == WM_DESTROY) cfg::writeByte("CList", "Docked", (BYTE)docked); if (!docked && msg->message != WM_CREATE && msg->message != WM_MOVING && msg->message != WM_CREATEDOCKED && msg->message != WM_MOVE) return 0; switch (msg->message) { case WM_CREATE: //if (GetSystemMetrics(SM_CMONITORS)>1) return 0; if (cfg::getByte("CList", "Docked", 0)) PostMessage(msg->hwnd, WM_CREATEDOCKED, 0, 0); draggingTitle = 0; return 0; case WM_CREATEDOCKED: //we need to post a message just after creation to let main message function do some work docked = (int)(char)cfg::getByte("CList", "Docked", 0); if (IsWindowVisible(msg->hwnd) && !IsIconic(msg->hwnd)) { RECT rc, rcMonitor; memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; abd.lParam = 0; abd.uCallbackMessage = WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW, &abd); GetWindowRect(msg->hwnd, &rc); Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor); Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc); MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); } break; case WM_ACTIVATE: memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; SHAppBarMessage(ABM_ACTIVATE, &abd); return 0; case WM_WINDOWPOSCHANGED: memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd); return 0; case WM_MOVING: { RECT rcMonitor; POINT ptCursor; // stop early if (GetAsyncKeyState(VK_CONTROL) & 0x8000) return 0; // GetMessagePos() is no good, position is always unsigned GetCursorPos(&ptCursor); Docking_GetMonitorRectFromPoint(ptCursor, &rcMonitor); if ((ptCursor.x < rcMonitor.left + EDGESENSITIVITY) || (ptCursor.x >= rcMonitor.right - EDGESENSITIVITY)) { if (!(GetWindowLongPtr(msg->hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) { SendMessage(msg->hwnd, CLUIINTM_REDRAW, 0, 0); MessageBox(0, TranslateT("The contact list cannot be docked when using the default title bar and border. Use a toolwindow or borderless style instead."), TranslateT("Contact list docking"), MB_OK); return 0; } memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; abd.lParam = 0; abd.uCallbackMessage = WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW, &abd); if (ptCursor.x < rcMonitor.left + EDGESENSITIVITY) docked = DOCKED_LEFT; else docked = DOCKED_RIGHT; SendMessage(msg->hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptCursor.x, ptCursor.y)); GetWindowRect(msg->hwnd, (LPRECT)msg->lParam); Docking_AdjustPosition(msg->hwnd, (LPRECT)&rcMonitor, (LPRECT)msg->lParam); PostMessage(msg->hwnd, CLUIINTM_REDRAW, 0, 0); return TRUE; } } return 0; case WM_MOVE: if (docked) { RECT rc, rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor); GetWindowRect(msg->hwnd, &rc); Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc); MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); return 1; } return 0; case WM_SIZING: { RECT rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor); Docking_AdjustPosition(msg->hwnd, &rcMonitor, (LPRECT)msg->lParam); *((LRESULT *)lParam) = TRUE; } return TRUE; case WM_SHOWWINDOW: if (msg->lParam) return 0; if ((msg->wParam && docked < 0) || (!msg->wParam && docked > 0)) docked = -docked; memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; if (msg->wParam) { RECT rc, rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd, &rcMonitor); abd.lParam = 0; abd.uCallbackMessage = WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW, &abd); GetWindowRect(msg->hwnd, &rc); Docking_AdjustPosition(msg->hwnd, &rcMonitor, &rc); MoveWindow(msg->hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE); } else SHAppBarMessage(ABM_REMOVE, &abd); return 0; case WM_NCHITTEST: { LONG result = DefWindowProc(msg->hwnd, WM_NCHITTEST, msg->wParam, msg->lParam); if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT) { *((LRESULT *)lParam) = HTCLIENT; return TRUE; } if (docked == DOCKED_LEFT && result == HTLEFT) { *((LRESULT *)lParam) = HTCLIENT; return TRUE; } if (docked == DOCKED_RIGHT && result == HTRIGHT) { *((LRESULT *)lParam) = HTCLIENT; return TRUE; } } return 0; case WM_SYSCOMMAND: if ((msg->wParam & 0xFFF0) != SC_MOVE) return 0; SetActiveWindow(msg->hwnd); SetCapture(msg->hwnd); draggingTitle = 1; *((LRESULT *)lParam) = 0; return TRUE; case WM_MOUSEMOVE: if (!draggingTitle) return 0; { RECT rc; POINT pt; GetClientRect(msg->hwnd, &rc); if (((docked == DOCKED_LEFT || docked == -DOCKED_LEFT) && (short)LOWORD(msg->lParam) > rc.right) || ((docked == DOCKED_RIGHT || docked == -DOCKED_RIGHT) && (short)LOWORD(msg->lParam) < 0)) { ReleaseCapture(); draggingTitle = 0; memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; SHAppBarMessage(ABM_REMOVE, &abd); docked = 0; GetCursorPos(&pt); PostMessage(msg->hwnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pt.x, pt.y)); SetWindowPos(msg->hwnd, 0, pt.x - rc.right / 2, pt.y - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYSMCAPTION) / 2, cluiPos.right, cluiPos.bottom, SWP_NOZORDER); } } return 1; case WM_LBUTTONUP: if (draggingTitle) { ReleaseCapture(); draggingTitle = 0; } return 0; case WM_DOCKCALLBACK: switch (msg->wParam) { case ABN_WINDOWARRANGE: ShowWindow(msg->hwnd, msg->lParam ? SW_HIDE : SW_SHOW); break; } return TRUE; case WM_DESTROY: if (docked > 0) { memset(&abd, 0, sizeof(abd)); abd.cbSize = sizeof(abd); abd.hWnd = msg->hwnd; SHAppBarMessage(ABM_REMOVE, &abd); } return 0; } return 0; }
int Docking_ProcessWindowMessage(WPARAM wParam,LPARAM lParam) { APPBARDATA abd; static int draggingTitle; MSG *msg=(MSG*)wParam; if(msg->message==WM_DESTROY) DBWriteContactSettingByte(NULL,"CList","Docked",(BYTE)docked); if(!docked && msg->message!=WM_CREATE && msg->message!=WM_MOVING && msg->message!=WM_CREATEDOCKED && msg->message != WM_MOVE && msg->message != WM_SIZE) return 0; switch(msg->message) { case WM_CREATE: //if(GetSystemMetrics(SM_CMONITORS)>1) return 0; if(DBGetContactSettingByte(NULL,"CList","Docked",0)) { PostMessage(msg->hwnd,WM_CREATEDOCKED,0,0); } draggingTitle=0; return 0; case WM_CREATEDOCKED: //we need to post a message just after creation to let main message function do some work docked=(int)(char)DBGetContactSettingByte(NULL,"CList","Docked",0); if(IsWindowVisible(msg->hwnd) && !IsIconic(msg->hwnd)) { RECT rc, rcMonitor; ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; abd.lParam=0; abd.uCallbackMessage=WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW,&abd); GetWindowRect(msg->hwnd,&rc); Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc); MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,TRUE); dock_prevent_moving=0; OnMoving(msg->hwnd,&rc); dock_prevent_moving=1; ReposButtons(msg->hwnd,0,NULL); } break; case WM_CAPTURECHANGED: ReposButtons(msg->hwnd,0,NULL); return 0; case WM_ACTIVATE: ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; SHAppBarMessage(ABM_ACTIVATE,&abd); return 0; case WM_SIZE: ReposButtons(msg->hwnd,1,NULL); return 0; case WM_WINDOWPOSCHANGED: { if (docked) ReposButtons(msg->hwnd,0,NULL); return 0; ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; SHAppBarMessage(ABM_WINDOWPOSCHANGED,&abd); ReposButtons(msg->hwnd,0,NULL); return 0; } case WM_MOVING: { RECT rcMonitor; RECT rcWindow; RECT *rc; int dx=0; POINT ptCursor; if (docked) return 0; // stop early if(!(GetAsyncKeyState(VK_CONTROL)&0x8000)) return 0; // GetMessagePos() is no good, position is always unsigned GetCursorPos(&ptCursor); GetWindowRect(msg->hwnd,&rcWindow); dock_drag_dx=rcWindow.left-ptCursor.x; dock_drag_dy=rcWindow.top-ptCursor.y; Docking_GetMonitorRectFromPoint(ptCursor,&rcMonitor); if(((ptCursor.x<rcMonitor.left+EDGESENSITIVITY) || (ptCursor.x>=rcMonitor.right-EDGESENSITIVITY)) ) { ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; abd.lParam=0; abd.uCallbackMessage=WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW,&abd); if(ptCursor.x<rcMonitor.left+EDGESENSITIVITY) docked=DOCKED_LEFT; else docked=DOCKED_RIGHT; // TempDock=1; GetWindowRect(msg->hwnd,(LPRECT)msg->lParam); rc=(RECT*)msg->lParam; if (docked==DOCKED_RIGHT) dx=(rc->right>rcMonitor.right)?rc->right-rcMonitor.right:0; else dx=(rc->left<rcMonitor.left)?rc->left-rcMonitor.left:0; OffsetRect(rc,-dx,0); Docking_AdjustPosition(msg->hwnd,(LPRECT)&rcMonitor,(LPRECT)msg->lParam); SendMessage(msg->hwnd,WM_SIZE,0,0); dock_prevent_moving=0; OnMoving(msg->hwnd,(LPRECT)msg->lParam); dock_prevent_moving=1; mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); DBWriteContactSettingByte(NULL,"CList","Docked",(BYTE)docked); ReposButtons(msg->hwnd,0,NULL); return TRUE; } return 0; } case WM_EXITSIZEMOVE: { RECT rcMonitor; RECT rcWindow; if (TempDock) TempDock=0; GetWindowRect(msg->hwnd,&rcWindow); Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rcWindow); *((LRESULT*)lParam)=TRUE; dock_prevent_moving=0; SetWindowPos(msg->hwnd,0,rcWindow.left,rcWindow.top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOSENDCHANGING); OnMoving(msg->hwnd,&rcWindow); ReposButtons(msg->hwnd,0,NULL);//-=-=-= dock_prevent_moving=1; return 1; } case WM_MOVE: { if(docked && 0) { RECT rc, rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); GetWindowRect(msg->hwnd,&rc); Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc); MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,TRUE); OnMoving(msg->hwnd,&rc); ReposButtons(msg->hwnd,0,NULL);//-=-=-= return 1; } ReposButtons(msg->hwnd,2,NULL); return 0; } case WM_SIZING: { /*RECT rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); Docking_AdjustPosition(msg->hwnd,&rcMonitor,(LPRECT)msg->lParam); *((LRESULT*)lParam)=TRUE; */ RECT rc; int dx=0, dy=0; int d=0; if (docked) ReposButtons(msg->hwnd,0,NULL); return FALSE; rc=*(RECT*)(msg->lParam); dock_prevent_moving=0; OnMoving(msg->hwnd,&rc); //-=-=-= return TRUE; } case WM_SHOWWINDOW: if(msg->lParam) return 0; if((msg->wParam && docked<0) || (!msg->wParam && docked>0)) docked=-docked; ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; if(msg->wParam) { RECT rc, rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); abd.lParam=0; abd.uCallbackMessage=WM_DOCKCALLBACK; SHAppBarMessage(ABM_NEW,&abd); GetWindowRect(msg->hwnd,&rc); Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc); MoveWindow(msg->hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,FALSE); OnMoving(msg->hwnd,&rc); ReposButtons(msg->hwnd,0,NULL);//-=-=-= } else { SHAppBarMessage(ABM_REMOVE,&abd); } return 0; case WM_NCHITTEST: { LONG result; result=DefWindowProc(msg->hwnd,WM_NCHITTEST,msg->wParam,msg->lParam); if(result==HTSIZE || result==HTTOP || result==HTTOPLEFT || result==HTTOPRIGHT || result==HTBOTTOM || result==HTBOTTOMRIGHT || result==HTBOTTOMLEFT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;} if(docked==DOCKED_LEFT && result==HTLEFT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;} if(docked==DOCKED_RIGHT && result==HTRIGHT) {*((LRESULT*)lParam)=HTCLIENT; return TRUE;} return 0; } case WM_SYSCOMMAND: if((msg->wParam&0xFFF0)!=SC_MOVE) return 0; SetActiveWindow(msg->hwnd); SetCapture(msg->hwnd); draggingTitle=1; *((LRESULT*)lParam)=0; return TRUE; case WM_MOUSEMOVE: if(!draggingTitle) return 0; { RECT rc; POINT pt; GetClientRect(msg->hwnd,&rc); if(((docked==DOCKED_LEFT || docked==-DOCKED_LEFT) && (short)LOWORD(msg->lParam)>rc.right) || ((docked==DOCKED_RIGHT || docked==-DOCKED_RIGHT) && (short)LOWORD(msg->lParam)<0)) { ReleaseCapture(); draggingTitle=0; ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; SHAppBarMessage(ABM_REMOVE,&abd); docked=0; GetCursorPos(&pt); PostMessage(msg->hwnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(pt.x,pt.y)); SetWindowPos(msg->hwnd,0,pt.x-rc.right/2,pt.y-GetSystemMetrics(SM_CYFRAME)-GetSystemMetrics(SM_CYSMCAPTION)/2,DBGetContactSettingDword(NULL,"CList","Width",0),DBGetContactSettingDword(NULL,"CList","Height",0),SWP_NOZORDER); DBWriteContactSettingByte(NULL,"CList","Docked",(BYTE)docked); // ReposButtons(msg->hwnd,0); } return 1; } case WM_LBUTTONUP: if(draggingTitle) { ReleaseCapture(); draggingTitle=0; } return 0; case WM_DOCKCALLBACK: switch(msg->wParam) { case ABN_WINDOWARRANGE: ShowWindowNew(msg->hwnd,msg->lParam?SW_HIDE:SW_SHOW); { RECT rc, rcMonitor; Docking_GetMonitorRectFromWindow(msg->hwnd,&rcMonitor); GetWindowRect(msg->hwnd,&rc); Docking_AdjustPosition(msg->hwnd,&rcMonitor,&rc); OnMoving(msg->hwnd,&rc); //-=-=-= ReposButtons(msg->hwnd,0,NULL); dock_prevent_moving=1; } break; } return TRUE; case WM_DESTROY: if(docked>0) { ZeroMemory(&abd,sizeof(abd)); abd.cbSize=sizeof(abd); abd.hWnd=msg->hwnd; SHAppBarMessage(ABM_REMOVE,&abd); ReposButtons(msg->hwnd,0,NULL); } return 0; } return 0; }
int fnDocking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam) { static int draggingTitle; MSG *msg = (MSG *) wParam; if (msg->message == WM_DESTROY) { if (docked) { db_set_b(NULL, "CList", "Docked", (BYTE) docked); db_set_dw(NULL, "CList", "DockX", (DWORD) dockPos.x); db_set_dw(NULL, "CList", "DockY", (DWORD) dockPos.y); } else { db_unset(NULL, "CList", "Docked"); db_unset(NULL, "CList", "DockX"); db_unset(NULL, "CList", "DockY"); } } if (!docked && msg->message != WM_CREATE && msg->message != WM_MOVING) return 0; switch (msg->message) { case WM_CREATE: draggingTitle = 0; docked = db_get_b(NULL, "CLUI", "DockToSides", 1) ? (char) db_get_b(NULL, "CList", "Docked", 0) : 0; dockPos.x = (int)db_get_dw(NULL, "CList", "DockX", 0); dockPos.y = (int)db_get_dw(NULL, "CList", "DockY", 0); break; case WM_ACTIVATE: Docking_Command(msg->hwnd, ABM_ACTIVATE); break; case WM_WINDOWPOSCHANGING: { LPWINDOWPOS wp = (LPWINDOWPOS)msg->lParam; bool vis = Docking_IsWindowVisible(msg->hwnd); if (wp->flags & SWP_SHOWWINDOW) vis = !IsIconic(msg->hwnd); if (wp->flags & SWP_HIDEWINDOW) vis = false; if (vis) { if (!(wp->flags & (SWP_NOMOVE | SWP_NOSIZE))) { bool addbar = Docking_Command(msg->hwnd, ABM_NEW) != 0; RECT rc = {0}; GetWindowRect(msg->hwnd, &rc); int cx = rc.right - rc.left; if (!(wp->flags & SWP_NOMOVE)) { rc.left = wp->x; rc.top = wp->y; } if (addbar) Docking_RectToDock(&rc); if (!(wp->flags & SWP_NOSIZE)) { rc.right = rc.left + wp->cx; rc.bottom = rc.top + wp->cy; addbar |= (cx != wp->cx); } Docking_SetSize(msg->hwnd, &rc, !addbar, false); if (!(wp->flags & SWP_NOMOVE)) { wp->x = rc.left; wp->y = rc.top; } if (!(wp->flags & SWP_NOSIZE)) wp->cy = rc.bottom - rc.top; *((LRESULT *) lParam) = TRUE; return TRUE; } else { if ((wp->flags & SWP_SHOWWINDOW) && Docking_Command(msg->hwnd, ABM_NEW)) { RECT rc = {0}; GetWindowRect(msg->hwnd, &rc); Docking_RectToDock(&rc); Docking_SetSize(msg->hwnd, &rc, false, false); wp->x = rc.left; wp->y = rc.top; wp->cy = rc.bottom - rc.top; wp->cx = rc.right - rc.left; wp->flags &= ~(SWP_NOSIZE | SWP_NOMOVE); } } } break; } case WM_WINDOWPOSCHANGED: { LPWINDOWPOS wp = (LPWINDOWPOS)msg->lParam; bool vis = Docking_IsWindowVisible(msg->hwnd); if (wp->flags & SWP_SHOWWINDOW) vis = !IsIconic(msg->hwnd); if (wp->flags & SWP_HIDEWINDOW) vis = false; if (!vis) Docking_Command(msg->hwnd, ABM_REMOVE); else Docking_Command(msg->hwnd, ABM_WINDOWPOSCHANGED); break; } case WM_DISPLAYCHANGE: if (Docking_IsWindowVisible(msg->hwnd)) { RECT rc = {0}; GetWindowRect(msg->hwnd, &rc); Docking_RectToDock(&rc); Docking_SetSize(msg->hwnd, &rc, false, true); } break; case WM_MOVING: if (!docked) { RECT rcMonitor; POINT ptCursor; // stop early if (GetAsyncKeyState(VK_CONTROL) & 0x8000) return 0; // GetMessagePos() is no good, position is always unsigned // GetCursorPos(&ptCursor); DWORD pos = GetMessagePos(); ptCursor.x = GET_X_LPARAM(pos); ptCursor.y = GET_Y_LPARAM(pos); Docking_GetMonitorRectFromPoint(&ptCursor, &rcMonitor); if (((ptCursor.x < rcMonitor.left + EDGESENSITIVITY) || (ptCursor.x >= rcMonitor.right - EDGESENSITIVITY)) && db_get_b(NULL, "CLUI", "DockToSides", 1)) { docked = (ptCursor.x < rcMonitor.left + EDGESENSITIVITY) ? DOCKED_LEFT : DOCKED_RIGHT; PostMessage(msg->hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptCursor.x, ptCursor.y)); Docking_Command(msg->hwnd, ABM_NEW); Docking_AdjustPosition(msg->hwnd, &rcMonitor, (LPRECT)msg->lParam, false, true); *((LRESULT *) lParam) = TRUE; return TRUE; } } break; case WM_NCHITTEST: switch (DefWindowProc(msg->hwnd, WM_NCHITTEST, msg->wParam, msg->lParam)) { case HTSIZE: case HTTOP: case HTTOPLEFT: case HTTOPRIGHT: case HTBOTTOM: case HTBOTTOMRIGHT: case HTBOTTOMLEFT: *((LRESULT *) lParam) = HTCLIENT; return TRUE; case HTLEFT: if (docked == DOCKED_LEFT) { *((LRESULT *) lParam) = HTCLIENT; return TRUE; } break; case HTRIGHT: if (docked == DOCKED_RIGHT) { *((LRESULT *) lParam) = HTCLIENT; return TRUE; } break; } break; case WM_SYSCOMMAND: if ((msg->wParam & 0xFFF0) != SC_MOVE) return 0; SetActiveWindow(msg->hwnd); SetCapture(msg->hwnd); draggingTitle = 1; *((LRESULT *) lParam) = 0; return 1; case WM_MOUSEMOVE: if (draggingTitle) { RECT rc; POINT pt; GetClientRect(msg->hwnd, &rc); if ((docked == DOCKED_LEFT && (short) LOWORD(msg->lParam) > rc.right) || (docked == DOCKED_RIGHT && (short) LOWORD(msg->lParam) < 0)) { ReleaseCapture(); draggingTitle = 0; docked = 0; GetCursorPos(&pt); PostMessage(msg->hwnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pt.x, pt.y)); SetWindowPos(msg->hwnd, 0, pt.x - rc.right / 2, pt.y - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYSMCAPTION) / 2, db_get_dw(NULL, "CList", "Width", 0), db_get_dw(NULL, "CList", "Height", 0), SWP_NOZORDER); Docking_Command(msg->hwnd, ABM_REMOVE); } return 1; } break; case WM_LBUTTONUP: if (draggingTitle) { ReleaseCapture(); draggingTitle = 0; } break; case WM_DOCKCALLBACK: switch (msg->wParam) { case ABN_WINDOWARRANGE: ShowWindow(msg->hwnd, msg->lParam ? SW_HIDE : SW_SHOW); break; case ABN_POSCHANGED: { RECT rc = {0}; GetWindowRect(msg->hwnd, &rc); Docking_SetSize(msg->hwnd, &rc, false, true); } break; } return 1; case WM_DESTROY: Docking_Command(msg->hwnd, ABM_REMOVE); break; } return 0; }