Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmonslctl.c
Go to the documentation of this file.
00001 00002 #include "desk.h" 00003 00004 static const TCHAR szMonitorSelWndClass[] = TEXT("MONITORSELWNDCLASS"); 00005 00006 typedef struct _MONSL_MON 00007 { 00008 RECT rc; 00009 HFONT hFont; 00010 TCHAR szCaption[12]; 00011 } MONSL_MON, *PMONSL_MON; 00012 00013 typedef struct _MONITORSELWND 00014 { 00015 HWND hSelf; 00016 HWND hNotify; 00017 HFONT hFont; 00018 SIZE ClientSize; 00019 DWORD UIState; 00020 union 00021 { 00022 DWORD dwInternalFlags; 00023 struct 00024 { 00025 UINT Enabled : 1; 00026 UINT HasFocus : 1; 00027 UINT CanDisplay : 1; 00028 UINT LeftBtnDown : 1; 00029 UINT IsDraggingMonitor : 1; 00030 }; 00031 }; 00032 DWORD ControlExStyle; 00033 DWORD MonitorsCount; 00034 INT SelectedMonitor; 00035 INT DraggingMonitor; 00036 RECT rcDragging; 00037 POINT ptDrag, ptDragBegin; 00038 SIZE DraggingMargin; 00039 PMONSL_MONINFO MonitorInfo; 00040 PMONSL_MON Monitors; 00041 RECT rcExtent; 00042 RECT rcMonitors; 00043 POINT ScrollPos; 00044 SIZE Margin; 00045 SIZE SelectionFrame; 00046 HBITMAP hbmDisabledPattern; 00047 HBRUSH hbrDisabled; 00048 } MONITORSELWND, *PMONITORSELWND; 00049 00050 static LRESULT 00051 MonSelNotify(IN PMONITORSELWND infoPtr, 00052 IN UINT code, 00053 IN OUT PVOID data) 00054 { 00055 LRESULT Ret = 0; 00056 00057 if (infoPtr->hNotify != NULL) 00058 { 00059 LPNMHDR pnmh = (LPNMHDR)data; 00060 00061 pnmh->hwndFrom = infoPtr->hSelf; 00062 pnmh->idFrom = GetWindowLongPtr(infoPtr->hSelf, 00063 GWLP_ID); 00064 pnmh->code = code; 00065 00066 Ret = SendMessage(infoPtr->hNotify, 00067 WM_NOTIFY, 00068 (WPARAM)pnmh->idFrom, 00069 (LPARAM)pnmh); 00070 } 00071 00072 return Ret; 00073 } 00074 00075 static LRESULT 00076 MonSelNotifyMonitor(IN PMONITORSELWND infoPtr, 00077 IN UINT code, 00078 IN INT Index, 00079 IN OUT PMONSL_MONNMHDR pmonnmh) 00080 { 00081 pmonnmh->Index = Index; 00082 00083 if (Index >= 0) 00084 { 00085 pmonnmh->MonitorInfo = infoPtr->MonitorInfo[Index]; 00086 } 00087 else 00088 { 00089 ZeroMemory(&pmonnmh->MonitorInfo, 00090 sizeof(pmonnmh->MonitorInfo)); 00091 } 00092 00093 return MonSelNotify(infoPtr, 00094 code, 00095 pmonnmh); 00096 } 00097 00098 static HFONT 00099 MonSelChangeFont(IN OUT PMONITORSELWND infoPtr, 00100 IN HFONT hFont, 00101 IN BOOL Redraw) 00102 { 00103 HFONT hOldFont = infoPtr->hFont; 00104 infoPtr->hFont = hFont; 00105 00106 if (Redraw) 00107 { 00108 InvalidateRect(infoPtr->hSelf, 00109 NULL, 00110 TRUE); 00111 } 00112 00113 return hOldFont; 00114 } 00115 00116 static VOID 00117 MonSelRectToScreen(IN PMONITORSELWND infoPtr, 00118 IN const RECT *prc, 00119 OUT PRECT prcOnScreen) 00120 { 00121 *prcOnScreen = *prc; 00122 OffsetRect(prcOnScreen, 00123 -infoPtr->ScrollPos.x, 00124 -infoPtr->ScrollPos.y); 00125 } 00126 00127 static VOID 00128 MonSelScreenToPt(IN PMONITORSELWND infoPtr, 00129 IN const POINT *pptOnScreen, 00130 OUT PPOINT ppt) 00131 { 00132 ppt->x = pptOnScreen->x + infoPtr->ScrollPos.x; 00133 ppt->y = pptOnScreen->y + infoPtr->ScrollPos.y; 00134 } 00135 00136 static VOID 00137 MonSelMonInfoToRect(IN const MONSL_MONINFO *pMonInfo, 00138 OUT PRECT prc) 00139 { 00140 prc->left = pMonInfo->Position.x; 00141 prc->top = pMonInfo->Position.y; 00142 prc->right = pMonInfo->Position.x + pMonInfo->Size.cx; 00143 prc->bottom = pMonInfo->Position.y + pMonInfo->Size.cy; 00144 } 00145 00146 static INT 00147 MonSelHitTest(IN PMONITORSELWND infoPtr, 00148 IN const POINT *ppt) 00149 { 00150 POINT pt; 00151 INT Index, Ret = -1; 00152 00153 if (infoPtr->CanDisplay) 00154 { 00155 MonSelScreenToPt(infoPtr, 00156 ppt, 00157 &pt); 00158 00159 for (Index = 0; Index < (INT)infoPtr->MonitorsCount; Index++) 00160 { 00161 if (PtInRect(&infoPtr->Monitors[Index].rc, 00162 pt)) 00163 { 00164 Ret = Index; 00165 break; 00166 } 00167 } 00168 } 00169 00170 return Ret; 00171 } 00172 00173 static VOID 00174 MonSelUpdateExtent(IN OUT PMONITORSELWND infoPtr) 00175 { 00176 DWORD Index; 00177 RECT rcMonitor; 00178 00179 /* NOTE: This routine calculates the extent of all monitor coordinates. 00180 These are not control coordinates! */ 00181 if (infoPtr->MonitorsCount > 0) 00182 { 00183 MonSelMonInfoToRect(&infoPtr->MonitorInfo[0], 00184 &infoPtr->rcExtent); 00185 00186 for (Index = 1; Index < infoPtr->MonitorsCount; Index++) 00187 { 00188 MonSelMonInfoToRect(&infoPtr->MonitorInfo[Index], 00189 &rcMonitor); 00190 00191 UnionRect(&infoPtr->rcExtent, 00192 &infoPtr->rcExtent, 00193 &rcMonitor); 00194 } 00195 } 00196 else 00197 { 00198 ZeroMemory(&infoPtr->rcExtent, 00199 sizeof(infoPtr->rcExtent)); 00200 } 00201 } 00202 00203 static VOID 00204 MonSelScaleRectRelative(IN const RECT *prcBaseFrom, 00205 IN const RECT *prcFrom, 00206 IN const RECT *prcBaseTo, 00207 OUT PRECT prcTo) 00208 { 00209 SIZE BaseFrom, BaseTo, From; 00210 00211 BaseFrom.cx = prcBaseFrom->right - prcBaseFrom->left; 00212 BaseFrom.cy = prcBaseFrom->bottom - prcBaseFrom->top; 00213 BaseTo.cx = prcBaseTo->right - prcBaseTo->left; 00214 BaseTo.cy = prcBaseTo->bottom - prcBaseTo->top; 00215 From.cx = prcFrom->right - prcFrom->left; 00216 From.cy = prcFrom->bottom - prcFrom->top; 00217 00218 prcTo->left = prcBaseTo->left + (((prcFrom->left - prcBaseFrom->left) * BaseTo.cx) / BaseFrom.cx); 00219 prcTo->top = prcBaseTo->top + (((prcFrom->top - prcBaseFrom->top) * BaseTo.cy) / BaseFrom.cy); 00220 prcTo->right = prcTo->left + ((From.cx * BaseTo.cx) / BaseFrom.cx); 00221 prcTo->bottom = prcTo->top + ((From.cy * BaseTo.cy) / BaseFrom.cy); 00222 } 00223 00224 static VOID 00225 ScaleRectSizeFit(IN const RECT *prcContainerRect, 00226 IN OUT PRECT prcRectToScale) 00227 { 00228 SIZE ContainerSize, RectSize; 00229 00230 ContainerSize.cx = prcContainerRect->right - prcContainerRect->left; 00231 ContainerSize.cy = prcContainerRect->bottom - prcContainerRect->top; 00232 RectSize.cx = prcRectToScale->right - prcRectToScale->left; 00233 RectSize.cy = prcRectToScale->bottom - prcRectToScale->top; 00234 00235 if (((RectSize.cx * 0xFFF) / RectSize.cy) < ((ContainerSize.cx * 0xFFF) / ContainerSize.cy)) 00236 { 00237 RectSize.cx = (RectSize.cx * ((ContainerSize.cy * 0xFFF) / RectSize.cy)) / 0xFFF; 00238 RectSize.cy = ContainerSize.cy; 00239 } 00240 else 00241 { 00242 RectSize.cy = (RectSize.cy * ((ContainerSize.cx * 0xFFF) / RectSize.cx)) / 0xFFF; 00243 RectSize.cx = ContainerSize.cx; 00244 } 00245 00246 prcRectToScale->right = prcRectToScale->left + RectSize.cx; 00247 prcRectToScale->bottom = prcRectToScale->top + RectSize.cy; 00248 00249 OffsetRect(prcRectToScale, 00250 prcContainerRect->left + ((ContainerSize.cx - RectSize.cx) / 2), 00251 prcContainerRect->top + ((ContainerSize.cy - RectSize.cy) / 2)); 00252 } 00253 00254 static VOID 00255 MonSelRepaint(IN PMONITORSELWND infoPtr) 00256 { 00257 RECT rc; 00258 00259 MonSelRectToScreen(infoPtr, 00260 &infoPtr->rcMonitors, 00261 &rc); 00262 InvalidateRect(infoPtr->hSelf, 00263 &rc, 00264 TRUE); 00265 } 00266 00267 static VOID 00268 MonSelRepaintMonitor(IN PMONITORSELWND infoPtr, 00269 IN DWORD Index) 00270 { 00271 RECT rc; 00272 BOOL NoRepaint = FALSE; 00273 00274 if (Index < infoPtr->MonitorsCount) 00275 { 00276 if (Index == (DWORD)infoPtr->DraggingMonitor) 00277 { 00278 if (infoPtr->IsDraggingMonitor) 00279 { 00280 MonSelRectToScreen(infoPtr, 00281 &infoPtr->rcDragging, 00282 &rc); 00283 } 00284 else 00285 NoRepaint = TRUE; 00286 } 00287 else 00288 { 00289 MonSelRectToScreen(infoPtr, 00290 &infoPtr->Monitors[Index].rc, 00291 &rc); 00292 } 00293 00294 if (!NoRepaint) 00295 { 00296 InvalidateRect(infoPtr->hSelf, 00297 &rc, 00298 TRUE); 00299 } 00300 } 00301 } 00302 00303 static VOID 00304 MonSelRepaintSelected(IN PMONITORSELWND infoPtr) 00305 { 00306 if (infoPtr->SelectedMonitor >= 0) 00307 { 00308 MonSelRepaintMonitor(infoPtr, 00309 (DWORD)infoPtr->SelectedMonitor); 00310 } 00311 } 00312 00313 static VOID 00314 MonSelResetMonitors(IN OUT PMONITORSELWND infoPtr) 00315 { 00316 DWORD Index; 00317 00318 for (Index = 0; Index < infoPtr->MonitorsCount; Index++) 00319 { 00320 if (infoPtr->Monitors[Index].hFont != NULL) 00321 { 00322 DeleteObject(infoPtr->Monitors[Index].hFont); 00323 infoPtr->Monitors[Index].hFont = NULL; 00324 } 00325 } 00326 } 00327 00328 00329 static VOID 00330 MonSelUpdateMonitorsInfo(IN OUT PMONITORSELWND infoPtr, 00331 IN BOOL bRepaint) 00332 { 00333 RECT rcExtSurface, rcExtDisplay; 00334 DWORD Index; 00335 00336 /* Recalculate rcExtent */ 00337 MonSelUpdateExtent(infoPtr); 00338 00339 infoPtr-> CanDisplay = infoPtr->MonitorsCount != 0 && 00340 (infoPtr->ClientSize.cx > (2 * (infoPtr->Margin.cx + infoPtr->SelectionFrame.cx))) && 00341 (infoPtr->ClientSize.cy > (2 * (infoPtr->Margin.cy + infoPtr->SelectionFrame.cy))); 00342 00343 if (infoPtr->CanDisplay) 00344 { 00345 /* Calculate the rectangle on the control in which may be painted */ 00346 rcExtSurface.left = infoPtr->Margin.cx; 00347 rcExtSurface.top = infoPtr->Margin.cy; 00348 rcExtSurface.right = rcExtSurface.left + infoPtr->ClientSize.cx - (2 * infoPtr->Margin.cx); 00349 rcExtSurface.bottom = rcExtSurface.top + infoPtr->ClientSize.cy - (2 * infoPtr->Margin.cy); 00350 00351 /* Calculate the rectangle on the control that is actually painted on */ 00352 rcExtDisplay.left = rcExtDisplay.top = 0; 00353 rcExtDisplay.right = infoPtr->rcExtent.right - infoPtr->rcExtent.left; 00354 rcExtDisplay.bottom = infoPtr->rcExtent.bottom - infoPtr->rcExtent.top; 00355 00356 ScaleRectSizeFit(&rcExtSurface, 00357 &rcExtDisplay); 00358 00359 infoPtr->rcMonitors = rcExtDisplay; 00360 00361 /* Now that we know in which area all monitors are located, 00362 calculate the monitors selection rectangles on the screen */ 00363 00364 for (Index = 0; Index < infoPtr->MonitorsCount; Index++) 00365 { 00366 MonSelMonInfoToRect(&infoPtr->MonitorInfo[Index], 00367 &rcExtDisplay); 00368 00369 MonSelScaleRectRelative(&infoPtr->rcExtent, 00370 &rcExtDisplay, 00371 &infoPtr->rcMonitors, 00372 &infoPtr->Monitors[Index].rc); 00373 } 00374 00375 MonSelResetMonitors(infoPtr); 00376 00377 if (bRepaint) 00378 MonSelRepaint(infoPtr); 00379 } 00380 else if (bRepaint) 00381 { 00382 InvalidateRect(infoPtr->hSelf, 00383 NULL, 00384 TRUE); 00385 } 00386 } 00387 00388 static BOOL 00389 MonSelSetMonitorsInfo(IN OUT PMONITORSELWND infoPtr, 00390 IN DWORD dwMonitors, 00391 IN const MONSL_MONINFO *MonitorsInfo) 00392 { 00393 DWORD Index; 00394 BOOL Ret = TRUE; 00395 00396 if (infoPtr->DraggingMonitor >= 0) 00397 return FALSE; 00398 00399 if (infoPtr->MonitorInfo != NULL) 00400 { 00401 LocalFree((HLOCAL)infoPtr->MonitorInfo); 00402 infoPtr->MonitorInfo = NULL; 00403 00404 MonSelResetMonitors(infoPtr); 00405 00406 LocalFree((HLOCAL)infoPtr->Monitors); 00407 infoPtr->Monitors = NULL; 00408 00409 infoPtr->MonitorsCount = 0; 00410 } 00411 00412 if (dwMonitors != 0) 00413 { 00414 infoPtr->MonitorInfo = (PMONSL_MONINFO)LocalAlloc(LMEM_FIXED, 00415 dwMonitors * sizeof(MONSL_MONINFO)); 00416 if (infoPtr->MonitorInfo != NULL) 00417 { 00418 infoPtr->Monitors = (PMONSL_MON)LocalAlloc(LMEM_FIXED, 00419 dwMonitors * sizeof(MONSL_MON)); 00420 if (infoPtr->Monitors != NULL) 00421 { 00422 CopyMemory(infoPtr->MonitorInfo, 00423 MonitorsInfo, 00424 dwMonitors * sizeof(MONSL_MONINFO)); 00425 ZeroMemory(infoPtr->Monitors, 00426 dwMonitors * sizeof(MONSL_MON)); 00427 00428 for (Index = 0; Index < dwMonitors; Index++) 00429 { 00430 _stprintf(infoPtr->Monitors[Index].szCaption, 00431 _T("%u"), 00432 Index + 1); 00433 } 00434 00435 infoPtr->MonitorsCount = dwMonitors; 00436 00437 if (infoPtr->SelectedMonitor >= (INT)infoPtr->MonitorsCount) 00438 infoPtr->SelectedMonitor = -1; 00439 00440 if (!(infoPtr->ControlExStyle & MSLM_EX_ALLOWSELECTNONE) && infoPtr->SelectedMonitor < 0) 00441 infoPtr->SelectedMonitor = 0; 00442 00443 MonSelUpdateMonitorsInfo(infoPtr, 00444 TRUE); 00445 } 00446 else 00447 { 00448 LocalFree((HLOCAL)infoPtr->MonitorInfo); 00449 infoPtr->MonitorInfo = NULL; 00450 00451 Ret = FALSE; 00452 } 00453 } 00454 else 00455 Ret = FALSE; 00456 } 00457 00458 if (!Ret) 00459 infoPtr->SelectedMonitor = -1; 00460 00461 if (!Ret || dwMonitors == 0) 00462 { 00463 InvalidateRect(infoPtr->hSelf, 00464 NULL, 00465 TRUE); 00466 } 00467 00468 return Ret; 00469 } 00470 00471 static DWORD 00472 MonSelGetMonitorsInfo(IN PMONITORSELWND infoPtr, 00473 IN DWORD dwMonitors, 00474 IN OUT PMONSL_MONINFO MonitorsInfo) 00475 { 00476 if (dwMonitors != 0) 00477 { 00478 if (dwMonitors > infoPtr->MonitorsCount) 00479 dwMonitors = infoPtr->MonitorsCount; 00480 00481 CopyMemory(MonitorsInfo, 00482 infoPtr->MonitorInfo, 00483 dwMonitors * sizeof(MONSL_MONINFO)); 00484 return dwMonitors; 00485 } 00486 else 00487 return infoPtr->MonitorsCount; 00488 } 00489 00490 static BOOL 00491 MonSelSetMonitorInfo(IN OUT PMONITORSELWND infoPtr, 00492 IN INT Index, 00493 IN const MONSL_MONINFO *MonitorsInfo) 00494 { 00495 if (infoPtr->DraggingMonitor < 0 && 00496 Index >= 0 && Index < (INT)infoPtr->MonitorsCount) 00497 { 00498 CopyMemory(&infoPtr->MonitorInfo[Index], 00499 MonitorsInfo, 00500 sizeof(MONSL_MONINFO)); 00501 00502 MonSelUpdateMonitorsInfo(infoPtr, 00503 TRUE); 00504 return TRUE; 00505 } 00506 00507 return FALSE; 00508 } 00509 00510 static BOOL 00511 MonSelGetMonitorInfo(IN PMONITORSELWND infoPtr, 00512 IN INT Index, 00513 IN OUT PMONSL_MONINFO MonitorsInfo) 00514 { 00515 if (Index >= 0 && Index < (INT)infoPtr->MonitorsCount) 00516 { 00517 CopyMemory(MonitorsInfo, 00518 &infoPtr->MonitorInfo[Index], 00519 sizeof(MONSL_MONINFO)); 00520 return TRUE; 00521 } 00522 00523 return FALSE; 00524 } 00525 00526 static INT 00527 MonSelGetMonitorRect(IN OUT PMONITORSELWND infoPtr, 00528 IN INT Index, 00529 OUT PRECT prc) 00530 { 00531 RECT rc, rcClient; 00532 00533 if (Index < 0 || Index >= infoPtr->MonitorsCount) 00534 return -1; 00535 00536 if (!infoPtr->CanDisplay) 00537 return 0; 00538 00539 MonSelRectToScreen(infoPtr, 00540 &infoPtr->Monitors[Index].rc, 00541 prc); 00542 00543 rcClient.left = rcClient.top = 0; 00544 rcClient.right = infoPtr->ClientSize.cx; 00545 rcClient.bottom = infoPtr->ClientSize.cy; 00546 00547 return IntersectRect(&rc, 00548 &rcClient, 00549 prc) != FALSE; 00550 } 00551 00552 static BOOL 00553 MonSelSetCurSelMonitor(IN OUT PMONITORSELWND infoPtr, 00554 IN INT Index, 00555 IN BOOL bNotify) 00556 { 00557 INT PrevSel; 00558 BOOL PreventSelect = FALSE; 00559 BOOL Ret = FALSE; 00560 00561 if (infoPtr->DraggingMonitor < 0 && 00562 (Index == -1 || Index < (INT)infoPtr->MonitorsCount)) 00563 { 00564 if (Index != infoPtr->SelectedMonitor) 00565 { 00566 if ((infoPtr->MonitorInfo[Index].Flags & MSL_MIF_DISABLED) && 00567 !(infoPtr->ControlExStyle & MSLM_EX_ALLOWSELECTDISABLED)) 00568 { 00569 PreventSelect = TRUE; 00570 } 00571 00572 if (!PreventSelect && bNotify) 00573 { 00574 MONSL_MONNMMONITORCHANGING nmi; 00575 00576 nmi.PreviousSelected = infoPtr->SelectedMonitor; 00577 nmi.AllowChanging = TRUE; 00578 00579 MonSelNotifyMonitor(infoPtr, 00580 MSLN_MONITORCHANGING, 00581 Index, 00582 &nmi.hdr); 00583 00584 PreventSelect = (nmi.AllowChanging == FALSE); 00585 } 00586 00587 if (!PreventSelect) 00588 { 00589 PrevSel = infoPtr->SelectedMonitor; 00590 infoPtr->SelectedMonitor = Index; 00591 00592 if (PrevSel >= 0) 00593 { 00594 MonSelRepaintMonitor(infoPtr, 00595 PrevSel); 00596 } 00597 00598 if (infoPtr->SelectedMonitor >= 0) 00599 MonSelRepaintSelected(infoPtr); 00600 00601 if (bNotify) 00602 { 00603 MONSL_MONNMHDR nm; 00604 00605 MonSelNotifyMonitor(infoPtr, 00606 MSLN_MONITORCHANGED, 00607 Index, 00608 &nm); 00609 } 00610 } 00611 } 00612 00613 Ret = TRUE; 00614 } 00615 00616 return Ret; 00617 } 00618 00619 static VOID 00620 MonSelCreate(IN OUT PMONITORSELWND infoPtr) 00621 { 00622 infoPtr->SelectionFrame.cx = infoPtr->SelectionFrame.cy = 4; 00623 infoPtr->Margin.cx = infoPtr->Margin.cy = 20; 00624 infoPtr->SelectedMonitor = -1; 00625 infoPtr->DraggingMonitor = -1; 00626 infoPtr->ControlExStyle = MSLM_EX_ALLOWSELECTDISABLED | MSLM_EX_HIDENUMBERONSINGLE | 00627 MSLM_EX_SELECTONRIGHTCLICK | MSLM_EX_SELECTBYARROWKEY; 00628 return; 00629 } 00630 00631 static VOID 00632 MonSelDestroy(IN OUT PMONITORSELWND infoPtr) 00633 { 00634 /* Free all monitors */ 00635 MonSelSetMonitorsInfo(infoPtr, 00636 0, 00637 NULL); 00638 00639 if (infoPtr->hbrDisabled != NULL) 00640 { 00641 DeleteObject(infoPtr->hbrDisabled); 00642 infoPtr->hbrDisabled = NULL; 00643 } 00644 00645 if (infoPtr->hbmDisabledPattern != NULL) 00646 { 00647 DeleteObject(infoPtr->hbmDisabledPattern); 00648 infoPtr->hbmDisabledPattern = NULL; 00649 } 00650 } 00651 00652 static BOOL 00653 MonSelSetExtendedStyle(IN OUT PMONITORSELWND infoPtr, 00654 IN DWORD dwExtendedStyle) 00655 { 00656 if (infoPtr->DraggingMonitor >= 0) 00657 return FALSE; 00658 00659 if (dwExtendedStyle != infoPtr->ControlExStyle) 00660 { 00661 infoPtr->ControlExStyle = dwExtendedStyle; 00662 00663 /* Repaint the control */ 00664 InvalidateRect(infoPtr->hSelf, 00665 NULL, 00666 TRUE); 00667 } 00668 00669 return TRUE; 00670 } 00671 00672 static DWORD 00673 MonSelGetExtendedStyle(IN PMONITORSELWND infoPtr) 00674 { 00675 return infoPtr->ControlExStyle; 00676 } 00677 00678 static HFONT 00679 MonSelGetMonitorFont(IN OUT PMONITORSELWND infoPtr, 00680 IN HDC hDC, 00681 IN INT Index) 00682 { 00683 TEXTMETRIC tm; 00684 SIZE rcsize; 00685 LOGFONT lf; 00686 HFONT hPrevFont, hFont; 00687 //INT len; 00688 00689 hFont = infoPtr->Monitors[Index].hFont; 00690 if (hFont == NULL && 00691 GetObject(infoPtr->hFont, 00692 sizeof(LOGFONT), 00693 &lf) != 0) 00694 { 00695 rcsize.cx = infoPtr->Monitors[Index].rc.right - infoPtr->Monitors[Index].rc.left - 00696 (2 * infoPtr->SelectionFrame.cx) - 2; 00697 rcsize.cy = infoPtr->Monitors[Index].rc.bottom - infoPtr->Monitors[Index].rc.top - 00698 (2 * infoPtr->SelectionFrame.cy) - 2; 00699 rcsize.cy = (rcsize.cy * 60) / 100; 00700 00701 //len = _tcslen(infoPtr->Monitors[Index].szCaption); 00702 00703 hPrevFont = SelectObject(hDC, 00704 infoPtr->hFont); 00705 00706 if (GetTextMetrics(hDC, 00707 &tm)) 00708 { 00709 lf.lfWeight = FW_SEMIBOLD; 00710 lf.lfHeight = -MulDiv(rcsize.cy - tm.tmExternalLeading, 00711 GetDeviceCaps(hDC, 00712 LOGPIXELSY), 00713 72); 00714 00715 hFont = CreateFontIndirect(&lf); 00716 if (hFont != NULL) 00717 infoPtr->Monitors[Index].hFont = hFont; 00718 } 00719 00720 SelectObject(hDC, 00721 hPrevFont); 00722 } 00723 00724 return hFont; 00725 } 00726 00727 static BOOL 00728 MonSelDrawDisabledRect(IN OUT PMONITORSELWND infoPtr, 00729 IN HDC hDC, 00730 IN const RECT *prc) 00731 { 00732 BOOL Ret = FALSE; 00733 00734 if (infoPtr->hbrDisabled == NULL) 00735 { 00736 static const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA}; 00737 00738 if (infoPtr->hbmDisabledPattern == NULL) 00739 { 00740 infoPtr->hbmDisabledPattern = CreateBitmap(8, 00741 8, 00742 1, 00743 1, 00744 Pattern); 00745 } 00746 00747 if (infoPtr->hbmDisabledPattern != NULL) 00748 infoPtr->hbrDisabled = CreatePatternBrush(infoPtr->hbmDisabledPattern); 00749 } 00750 00751 if (infoPtr->hbrDisabled != NULL) 00752 { 00753 /* FIXME: Implement */ 00754 } 00755 00756 return Ret; 00757 } 00758 00759 static VOID 00760 MonSelPaintMonitor(IN OUT PMONITORSELWND infoPtr, 00761 IN HDC hDC, 00762 IN DWORD Index, 00763 IN OUT PRECT prc, 00764 IN COLORREF crDefFontColor, 00765 IN BOOL bHideNumber) 00766 { 00767 HFONT hFont, hPrevFont; 00768 COLORREF crPrevText; 00769 00770 if ((INT)Index == infoPtr->SelectedMonitor) 00771 { 00772 FillRect(hDC, 00773 prc, 00774 (HBRUSH)(COLOR_HIGHLIGHT + 1)); 00775 00776 if (infoPtr->HasFocus && !(infoPtr->UIState & UISF_HIDEFOCUS)) 00777 { 00778 /* NOTE: We need to switch the text color to the default, because 00779 DrawFocusRect draws a solid line if the text is white! */ 00780 00781 crPrevText = SetTextColor(hDC, 00782 crDefFontColor); 00783 00784 DrawFocusRect(hDC, 00785 prc); 00786 00787 SetTextColor(hDC, 00788 crPrevText); 00789 } 00790 } 00791 00792 InflateRect(prc, 00793 -infoPtr->SelectionFrame.cx, 00794 -infoPtr->SelectionFrame.cy); 00795 00796 Rectangle(hDC, 00797 prc->left, 00798 prc->top, 00799 prc->right, 00800 prc->bottom); 00801 00802 InflateRect(prc, 00803 -1, 00804 -1); 00805 00806 if (!bHideNumber) 00807 { 00808 hFont = MonSelGetMonitorFont(infoPtr, 00809 hDC, 00810 Index); 00811 if (hFont != NULL) 00812 { 00813 hPrevFont = SelectObject(hDC, 00814 hFont); 00815 00816 DrawText(hDC, 00817 infoPtr->Monitors[Index].szCaption, 00818 -1, 00819 prc, 00820 DT_VCENTER | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE); 00821 00822 SelectObject(hDC, 00823 hPrevFont); 00824 } 00825 } 00826 00827 if (infoPtr->MonitorInfo[Index].Flags & MSL_MIF_DISABLED) 00828 { 00829 InflateRect(prc, 00830 1, 00831 1); 00832 00833 MonSelDrawDisabledRect(infoPtr, 00834 hDC, 00835 prc); 00836 } 00837 } 00838 00839 static VOID 00840 MonSelPaint(IN OUT PMONITORSELWND infoPtr, 00841 IN HDC hDC, 00842 IN const RECT *prcUpdate) 00843 { 00844 COLORREF crPrevText; 00845 HBRUSH hbBk, hbOldBk; 00846 HPEN hpFg, hpOldFg; 00847 DWORD Index; 00848 RECT rc, rctmp; 00849 INT iPrevBkMode; 00850 BOOL bHideNumber; 00851 00852 bHideNumber = (infoPtr->ControlExStyle & MSLM_EX_HIDENUMBERS) || 00853 ((infoPtr->MonitorsCount == 1) && (infoPtr->ControlExStyle & MSLM_EX_HIDENUMBERONSINGLE)); 00854 00855 hbBk = GetSysColorBrush(COLOR_BACKGROUND); 00856 hpFg = CreatePen(PS_SOLID, 00857 0, 00858 GetSysColor(COLOR_HIGHLIGHTTEXT)); 00859 00860 hbOldBk = SelectObject(hDC, 00861 hbBk); 00862 hpOldFg = SelectObject(hDC, 00863 hpFg); 00864 iPrevBkMode = SetBkMode(hDC, 00865 TRANSPARENT); 00866 crPrevText = SetTextColor(hDC, 00867 GetSysColor(COLOR_HIGHLIGHTTEXT)); 00868 00869 for (Index = 0; Index < infoPtr->MonitorsCount; Index++) 00870 { 00871 if (infoPtr->IsDraggingMonitor && 00872 (DWORD)infoPtr->DraggingMonitor == Index) 00873 { 00874 continue; 00875 } 00876 00877 MonSelRectToScreen(infoPtr, 00878 &infoPtr->Monitors[Index].rc, 00879 &rc); 00880 00881 if (IntersectRect(&rctmp, 00882 &rc, 00883 prcUpdate)) 00884 { 00885 MonSelPaintMonitor(infoPtr, 00886 hDC, 00887 Index, 00888 &rc, 00889 crPrevText, 00890 bHideNumber); 00891 } 00892 } 00893 00894 /* Paint the dragging monitor last */ 00895 if (infoPtr->IsDraggingMonitor && 00896 infoPtr->DraggingMonitor >= 0) 00897 { 00898 MonSelRectToScreen(infoPtr, 00899 &infoPtr->rcDragging, 00900 &rc); 00901 00902 if (IntersectRect(&rctmp, 00903 &rc, 00904 prcUpdate)) 00905 { 00906 MonSelPaintMonitor(infoPtr, 00907 hDC, 00908 (DWORD)infoPtr->DraggingMonitor, 00909 &rc, 00910 crPrevText, 00911 bHideNumber); 00912 } 00913 } 00914 00915 SetTextColor(hDC, 00916 crPrevText); 00917 SetBkMode(hDC, 00918 iPrevBkMode); 00919 SelectObject(hDC, 00920 hpOldFg); 00921 SelectObject(hDC, 00922 hbOldBk); 00923 00924 DeleteObject(hpFg); 00925 } 00926 00927 static VOID 00928 MonSelContextMenu(IN OUT PMONITORSELWND infoPtr, 00929 IN SHORT x, 00930 IN SHORT y) 00931 { 00932 MONSL_MONNMBUTTONCLICKED nm; 00933 INT Index; 00934 00935 if (!infoPtr->HasFocus) 00936 SetFocus(infoPtr->hSelf); 00937 00938 nm.pt.x = x; 00939 nm.pt.y = y; 00940 00941 Index = MonSelHitTest(infoPtr, 00942 &nm.pt); 00943 00944 MonSelNotifyMonitor(infoPtr, 00945 MSLN_RBUTTONUP, 00946 Index, 00947 (PMONSL_MONNMHDR)&nm); 00948 00949 /* Send a WM_CONTEXTMENU notification */ 00950 MapWindowPoints(infoPtr->hSelf, 00951 NULL, 00952 &nm.pt, 00953 1); 00954 00955 SendMessage(infoPtr->hSelf, 00956 WM_CONTEXTMENU, 00957 (WPARAM)infoPtr->hSelf, 00958 MAKELPARAM(nm.pt.x, 00959 nm.pt.y)); 00960 } 00961 00962 static VOID 00963 MonSelApplyCursorClipping(IN PMONITORSELWND infoPtr, 00964 IN BOOL bClip) 00965 { 00966 RECT rc; 00967 00968 if (bClip) 00969 { 00970 rc.left = rc.top = 0; 00971 rc.right = infoPtr->ClientSize.cx; 00972 rc.bottom = infoPtr->ClientSize.cy; 00973 00974 if (MapWindowPoints(infoPtr->hSelf, 00975 NULL, 00976 (LPPOINT)&rc, 00977 2)) 00978 { 00979 ClipCursor(&rc); 00980 } 00981 } 00982 else 00983 { 00984 ClipCursor(NULL); 00985 } 00986 } 00987 00988 static VOID 00989 MonSelMoveDragRect(IN OUT PMONITORSELWND infoPtr, 00990 IN PPOINT ppt) 00991 { 00992 RECT rcPrev, rcUpdate, *prc; 00993 HRGN hRgnPrev; 00994 HDC hDC; 00995 00996 if (infoPtr->CanDisplay) 00997 { 00998 hDC = GetDC(infoPtr->hSelf); 00999 if (hDC != NULL) 01000 { 01001 if (infoPtr->ptDrag.x != ppt->x || 01002 infoPtr->ptDrag.y != ppt->y) 01003 { 01004 infoPtr->ptDrag = *ppt; 01005 01006 rcPrev = infoPtr->rcDragging; 01007 01008 /* Calculate updated dragging rectangle */ 01009 prc = &infoPtr->Monitors[infoPtr->DraggingMonitor].rc; 01010 infoPtr->rcDragging.left = ppt->x - infoPtr->DraggingMargin.cx; 01011 infoPtr->rcDragging.top = ppt->y - infoPtr->DraggingMargin.cy; 01012 infoPtr->rcDragging.right = infoPtr->rcDragging.left + (prc->right - prc->left); 01013 infoPtr->rcDragging.bottom = infoPtr->rcDragging.top + (prc->bottom - prc->top); 01014 01015 hRgnPrev = CreateRectRgn(rcPrev.left, 01016 rcPrev.top, 01017 rcPrev.right, 01018 rcPrev.bottom); 01019 01020 if (hRgnPrev != NULL) 01021 { 01022 if (!ScrollDC(hDC, 01023 infoPtr->rcDragging.left - rcPrev.left, 01024 infoPtr->rcDragging.top - rcPrev.top, 01025 &rcPrev, 01026 NULL, 01027 hRgnPrev, 01028 &rcUpdate) || 01029 !InvalidateRgn(infoPtr->hSelf, 01030 hRgnPrev, 01031 TRUE)) 01032 { 01033 DeleteObject(hRgnPrev); 01034 goto InvRects; 01035 } 01036 01037 DeleteObject(hRgnPrev); 01038 } 01039 else 01040 { 01041 InvRects: 01042 InvalidateRect(infoPtr->hSelf, 01043 &rcPrev, 01044 TRUE); 01045 InvalidateRect(infoPtr->hSelf, 01046 &infoPtr->rcDragging, 01047 TRUE); 01048 } 01049 } 01050 01051 ReleaseDC(infoPtr->hSelf, 01052 hDC); 01053 } 01054 } 01055 } 01056 01057 static VOID 01058 MonSelCancelDragging(IN OUT PMONITORSELWND infoPtr) 01059 { 01060 DWORD Index; 01061 01062 if (infoPtr->DraggingMonitor >= 0) 01063 { 01064 MonSelMoveDragRect(infoPtr, 01065 &infoPtr->ptDragBegin); 01066 01067 Index = (DWORD)infoPtr->DraggingMonitor; 01068 infoPtr->DraggingMonitor = -1; 01069 01070 if (infoPtr->CanDisplay) 01071 { 01072 /* Repaint the area where the monitor was last dragged */ 01073 MonSelRepaintMonitor(infoPtr, 01074 Index); 01075 01076 infoPtr->IsDraggingMonitor = FALSE; 01077 01078 /* Repaint the area where the monitor is located */ 01079 MonSelRepaintMonitor(infoPtr, 01080 Index); 01081 } 01082 else 01083 infoPtr->IsDraggingMonitor = FALSE; 01084 01085 ReleaseCapture(); 01086 01087 MonSelApplyCursorClipping(infoPtr, 01088 FALSE); 01089 } 01090 } 01091 01092 static VOID 01093 MonSelInitDragging(IN OUT PMONITORSELWND infoPtr, 01094 IN DWORD Index, 01095 IN PPOINT ppt) 01096 { 01097 POINT pt; 01098 01099 MonSelCancelDragging(infoPtr); 01100 infoPtr->IsDraggingMonitor = FALSE; 01101 01102 MonSelScreenToPt(infoPtr, 01103 ppt, 01104 &pt); 01105 01106 infoPtr->ptDrag = infoPtr->ptDragBegin = pt; 01107 infoPtr->DraggingMonitor = (INT)Index; 01108 01109 infoPtr->DraggingMargin.cx = ppt->x - infoPtr->Monitors[Index].rc.left; 01110 infoPtr->DraggingMargin.cy = ppt->y - infoPtr->Monitors[Index].rc.top; 01111 infoPtr->rcDragging = infoPtr->Monitors[Index].rc; 01112 01113 MonSelApplyCursorClipping(infoPtr, 01114 TRUE); 01115 } 01116 01117 static VOID 01118 MonSelDrag(IN OUT PMONITORSELWND infoPtr, 01119 IN PPOINT ppt) 01120 { 01121 SIZE szDrag; 01122 POINT pt; 01123 RECT rcDrag; 01124 01125 if (infoPtr->DraggingMonitor >= 0) 01126 { 01127 MonSelScreenToPt(infoPtr, 01128 ppt, 01129 &pt); 01130 01131 if (!infoPtr->IsDraggingMonitor) 01132 { 01133 szDrag.cx = GetSystemMetrics(SM_CXDRAG); 01134 szDrag.cy = GetSystemMetrics(SM_CYDRAG); 01135 01136 rcDrag.left = infoPtr->Monitors[infoPtr->DraggingMonitor].rc.left + infoPtr->DraggingMargin.cx - (szDrag.cx / 2); 01137 rcDrag.top = infoPtr->Monitors[infoPtr->DraggingMonitor].rc.top + infoPtr->DraggingMargin.cy - (szDrag.cy / 2); 01138 rcDrag.right = rcDrag.left + szDrag.cx; 01139 rcDrag.bottom = rcDrag.top + szDrag.cy; 01140 01141 if (!PtInRect(&rcDrag, 01142 pt)) 01143 { 01144 /* The user started moving around the mouse: Begin dragging */ 01145 infoPtr->IsDraggingMonitor = TRUE; 01146 MonSelMoveDragRect(infoPtr, 01147 &pt); 01148 } 01149 } 01150 else 01151 { 01152 MonSelMoveDragRect(infoPtr, 01153 &pt); 01154 } 01155 } 01156 } 01157 01158 static LRESULT CALLBACK 01159 MonitorSelWndProc(IN HWND hwnd, 01160 IN UINT uMsg, 01161 IN WPARAM wParam, 01162 IN LPARAM lParam) 01163 { 01164 PMONITORSELWND infoPtr; 01165 LRESULT Ret = 0; 01166 01167 infoPtr = (PMONITORSELWND)GetWindowLongPtrW(hwnd, 01168 0); 01169 01170 if (infoPtr == NULL && uMsg != WM_CREATE) 01171 { 01172 goto HandleDefaultMessage; 01173 } 01174 01175 switch (uMsg) 01176 { 01177 case WM_PAINT: 01178 case WM_PRINTCLIENT: 01179 { 01180 PAINTSTRUCT ps; 01181 HDC hDC; 01182 01183 if (wParam != 0) 01184 { 01185 if (!GetUpdateRect(hwnd, 01186 &ps.rcPaint, 01187 TRUE)) 01188 { 01189 break; 01190 } 01191 hDC = (HDC)wParam; 01192 } 01193 else 01194 { 01195 hDC = BeginPaint(hwnd, 01196 &ps); 01197 if (hDC == NULL) 01198 { 01199 break; 01200 } 01201 } 01202 01203 if (infoPtr->CanDisplay) 01204 { 01205 MonSelPaint(infoPtr, 01206 hDC, 01207 &ps.rcPaint); 01208 } 01209 01210 if (wParam == 0) 01211 { 01212 EndPaint(hwnd, 01213 &ps); 01214 } 01215 break; 01216 } 01217 01218 case WM_MOUSEMOVE: 01219 { 01220 POINT pt; 01221 01222 if (!(wParam & MK_LBUTTON)) 01223 { 01224 MonSelCancelDragging(infoPtr); 01225 break; 01226 } 01227 01228 if (infoPtr->LeftBtnDown) 01229 { 01230 pt.x = (LONG)LOWORD(lParam); 01231 pt.y = (LONG)HIWORD(lParam); 01232 01233 MonSelDrag(infoPtr, 01234 &pt); 01235 } 01236 01237 break; 01238 } 01239 01240 case WM_RBUTTONDOWN: 01241 { 01242 if (!(infoPtr->ControlExStyle & MSLM_EX_SELECTONRIGHTCLICK)) 01243 break; 01244 01245 /* Fall through */ 01246 } 01247 01248 case WM_LBUTTONDBLCLK: 01249 case WM_LBUTTONDOWN: 01250 { 01251 INT Index; 01252 POINT pt; 01253 01254 if (!infoPtr->HasFocus) 01255 SetFocus(infoPtr->hSelf); 01256 01257 pt.x = (LONG)LOWORD(lParam); 01258 pt.y = (LONG)HIWORD(lParam); 01259 01260 Index = MonSelHitTest(infoPtr, 01261 &pt); 01262 if (Index >= 0 || (infoPtr->ControlExStyle & MSLM_EX_ALLOWSELECTNONE)) 01263 { 01264 MonSelSetCurSelMonitor(infoPtr, 01265 Index, 01266 TRUE); 01267 } 01268 01269 if (Index >= 0 && (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK)) 01270 { 01271 infoPtr->LeftBtnDown = TRUE; 01272 MonSelInitDragging(infoPtr, 01273 (DWORD)Index, 01274 &pt); 01275 } 01276 01277 /* Fall through */ 01278 } 01279 01280 case WM_MBUTTONDOWN: 01281 { 01282 if (!infoPtr->HasFocus) 01283 SetFocus(hwnd); 01284 break; 01285 } 01286 01287 case WM_RBUTTONUP: 01288 { 01289 MonSelContextMenu(infoPtr, 01290 (SHORT)LOWORD(lParam), 01291 (SHORT)HIWORD(lParam)); 01292 break; 01293 } 01294 01295 case WM_LBUTTONUP: 01296 { 01297 MonSelCancelDragging(infoPtr); 01298 infoPtr->LeftBtnDown = FALSE; 01299 break; 01300 } 01301 01302 case WM_GETDLGCODE: 01303 { 01304 INT virtKey; 01305 01306 virtKey = (lParam != 0 ? (INT)((LPMSG)lParam)->wParam : 0); 01307 switch (virtKey) 01308 { 01309 case VK_TAB: 01310 { 01311 /* Change the UI status */ 01312 SendMessage(GetAncestor(hwnd, 01313 GA_PARENT), 01314 WM_CHANGEUISTATE, 01315 MAKEWPARAM(UIS_INITIALIZE, 01316 0), 01317 0); 01318 break; 01319 } 01320 } 01321 01322 Ret |= DLGC_WANTARROWS; 01323 01324 if (infoPtr->ControlExStyle & MSLM_EX_SELECTBYNUMKEY) 01325 Ret |= DLGC_WANTCHARS; 01326 break; 01327 } 01328 01329 case WM_SETFOCUS: 01330 { 01331 infoPtr->HasFocus = TRUE; 01332 MonSelRepaintSelected(infoPtr); 01333 break; 01334 } 01335 01336 case WM_KILLFOCUS: 01337 { 01338 infoPtr->HasFocus = FALSE; 01339 MonSelCancelDragging(infoPtr); 01340 MonSelRepaintSelected(infoPtr); 01341 break; 01342 } 01343 01344 case WM_UPDATEUISTATE: 01345 { 01346 DWORD OldUIState; 01347 01348 Ret = DefWindowProcW(hwnd, 01349 uMsg, 01350 wParam, 01351 lParam); 01352 01353 OldUIState = infoPtr->UIState; 01354 switch (LOWORD(wParam)) 01355 { 01356 case UIS_SET: 01357 infoPtr->UIState |= HIWORD(wParam); 01358 break; 01359 01360 case UIS_CLEAR: 01361 infoPtr->UIState &= ~HIWORD(wParam); 01362 break; 01363 } 01364 01365 if (infoPtr->UIState != OldUIState) 01366 MonSelRepaintSelected(infoPtr); 01367 break; 01368 } 01369 01370 case WM_SETFONT: 01371 { 01372 Ret = (LRESULT)MonSelChangeFont(infoPtr, 01373 (HFONT)wParam, 01374 (BOOL)LOWORD(lParam)); 01375 break; 01376 } 01377 01378 case WM_SIZE: 01379 { 01380 infoPtr->ClientSize.cx = LOWORD(lParam); 01381 infoPtr->ClientSize.cy = HIWORD(lParam); 01382 01383 /* Don't let MonSelUpdateMonitorsInfo repaint the control 01384 because this won't work properly in case the control 01385 was sized down! */ 01386 MonSelUpdateMonitorsInfo(infoPtr, 01387 FALSE); 01388 InvalidateRect(infoPtr->hSelf, 01389 NULL, 01390 TRUE); 01391 break; 01392 } 01393 01394 case WM_GETFONT: 01395 { 01396 Ret = (LRESULT)infoPtr->hFont; 01397 break; 01398 } 01399 01400 case WM_ENABLE: 01401 { 01402 infoPtr->Enabled = ((BOOL)wParam != FALSE); 01403 MonSelRepaint(infoPtr); 01404 break; 01405 } 01406 01407 case WM_STYLECHANGED: 01408 { 01409 if (wParam == GWL_STYLE) 01410 { 01411 unsigned int OldEnabled = infoPtr->Enabled; 01412 infoPtr->Enabled = !(((LPSTYLESTRUCT)lParam)->styleNew & WS_DISABLED); 01413 01414 if (OldEnabled != infoPtr->Enabled) 01415 MonSelRepaint(infoPtr); 01416 } 01417 break; 01418 } 01419 01420 case WM_KEYDOWN: 01421 { 01422 INT Index; 01423 01424 if (infoPtr->ControlExStyle & MSLM_EX_SELECTBYARROWKEY) 01425 { 01426 switch (wParam) 01427 { 01428 case VK_UP: 01429 case VK_LEFT: 01430 { 01431 Index = infoPtr->SelectedMonitor; 01432 01433 if (infoPtr->MonitorsCount != 0) 01434 { 01435 if (Index < 0) 01436 Index = 0; 01437 else if (Index > 0) 01438 Index--; 01439 } 01440 01441 if (Index >= 0) 01442 { 01443 MonSelSetCurSelMonitor(infoPtr, 01444 Index, 01445 TRUE); 01446 } 01447 break; 01448 } 01449 01450 case VK_DOWN: 01451 case VK_RIGHT: 01452 { 01453 Index = infoPtr->SelectedMonitor; 01454 01455 if (infoPtr->MonitorsCount != 0) 01456 { 01457 if (Index < 0) 01458 Index = (INT)infoPtr->MonitorsCount - 1; 01459 else if (Index < (INT)infoPtr->MonitorsCount - 1) 01460 Index++; 01461 } 01462 01463 if (infoPtr->SelectedMonitor < infoPtr->MonitorsCount) 01464 { 01465 MonSelSetCurSelMonitor(infoPtr, 01466 Index, 01467 TRUE); 01468 } 01469 break; 01470 } 01471 } 01472 } 01473 break; 01474 } 01475 01476 case WM_CHAR: 01477 { 01478 if ((infoPtr->ControlExStyle & MSLM_EX_SELECTBYNUMKEY) && 01479 wParam >= '1' && wParam <= '9') 01480 { 01481 INT Index = (INT)(wParam - '1'); 01482 if (Index < (INT)infoPtr->MonitorsCount) 01483 { 01484 MonSelSetCurSelMonitor(infoPtr, 01485 Index, 01486 TRUE); 01487 } 01488 } 01489 break; 01490 } 01491 01492 case MSLM_SETMONITORSINFO: 01493 { 01494 Ret = MonSelSetMonitorsInfo(infoPtr, 01495 (DWORD)wParam, 01496 (const MONSL_MONINFO *)lParam); 01497 break; 01498 } 01499 01500 case MSLM_GETMONITORSINFO: 01501 { 01502 Ret = MonSelGetMonitorsInfo(infoPtr, 01503 (DWORD)wParam, 01504 (PMONSL_MONINFO)lParam); 01505 break; 01506 } 01507 01508 case MSLM_GETMONITORINFOCOUNT: 01509 { 01510 Ret = infoPtr->MonitorsCount; 01511 break; 01512 } 01513 01514 case MSLM_HITTEST: 01515 { 01516 Ret = MonSelHitTest(infoPtr, 01517 (const POINT *)wParam); 01518 break; 01519 } 01520 01521 case MSLM_SETCURSEL: 01522 { 01523 Ret = MonSelSetCurSelMonitor(infoPtr, 01524 (INT)wParam, 01525 FALSE); 01526 break; 01527 } 01528 01529 case MSLM_GETCURSEL: 01530 { 01531 Ret = infoPtr->SelectedMonitor; 01532 break; 01533 } 01534 01535 case MSLM_SETMONITORINFO: 01536 { 01537 Ret = MonSelSetMonitorInfo(infoPtr, 01538 (INT)wParam, 01539 (const MONSL_MONINFO *)lParam); 01540 break; 01541 } 01542 01543 case MSLM_GETMONITORINFO: 01544 { 01545 Ret = MonSelGetMonitorInfo(infoPtr, 01546 (INT)wParam, 01547 (PMONSL_MONINFO)lParam); 01548 break; 01549 } 01550 01551 case MSLM_SETEXSTYLE: 01552 { 01553 Ret = MonSelSetExtendedStyle(infoPtr, 01554 (DWORD)lParam); 01555 break; 01556 } 01557 01558 case MSLM_GETEXSTYLE: 01559 { 01560 Ret = MonSelGetExtendedStyle(infoPtr); 01561 break; 01562 } 01563 01564 case MSLM_GETMONITORRECT: 01565 { 01566 Ret = (LRESULT)MonSelGetMonitorRect(infoPtr, 01567 (INT)wParam, 01568 (PRECT)lParam); 01569 break; 01570 } 01571 01572 case WM_CREATE: 01573 { 01574 infoPtr = (PMONITORSELWND) HeapAlloc(GetProcessHeap(), 01575 0, 01576 sizeof(MONITORSELWND)); 01577 if (infoPtr == NULL) 01578 { 01579 Ret = (LRESULT)-1; 01580 break; 01581 } 01582 01583 ZeroMemory(infoPtr, 01584 sizeof(MONITORSELWND)); 01585 infoPtr->hSelf = hwnd; 01586 infoPtr->hNotify = ((LPCREATESTRUCTW)lParam)->hwndParent; 01587 infoPtr->Enabled = !(((LPCREATESTRUCTW)lParam)->style & WS_DISABLED); 01588 infoPtr->UIState = SendMessage(hwnd, 01589 WM_QUERYUISTATE, 01590 0, 01591 0); 01592 01593 SetWindowLongPtrW(hwnd, 01594 0, 01595 (LONG_PTR)infoPtr); 01596 01597 MonSelCreate(infoPtr); 01598 break; 01599 } 01600 01601 case WM_DESTROY: 01602 { 01603 MonSelDestroy(infoPtr); 01604 01605 HeapFree(GetProcessHeap(), 01606 0, 01607 infoPtr); 01608 SetWindowLongPtrW(hwnd, 01609 0, 01610 (DWORD_PTR)NULL); 01611 break; 01612 } 01613 01614 default: 01615 { 01616 HandleDefaultMessage: 01617 Ret = DefWindowProcW(hwnd, 01618 uMsg, 01619 wParam, 01620 lParam); 01621 break; 01622 } 01623 } 01624 01625 return Ret; 01626 } 01627 01628 BOOL 01629 RegisterMonitorSelectionControl(IN HINSTANCE hInstance) 01630 { 01631 WNDCLASS wc = {0}; 01632 01633 wc.style = CS_DBLCLKS; 01634 wc.lpfnWndProc = MonitorSelWndProc; 01635 wc.cbWndExtra = sizeof(PMONITORSELWND); 01636 wc.hInstance = hInstance; 01637 wc.hCursor = LoadCursorW(NULL, 01638 (LPWSTR)IDC_ARROW); 01639 wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); 01640 wc.lpszClassName = szMonitorSelWndClass; 01641 01642 return RegisterClass(&wc) != 0; 01643 } 01644 01645 VOID 01646 UnregisterMonitorSelectionControl(IN HINSTANCE hInstance) 01647 { 01648 UnregisterClassW(szMonitorSelWndClass, 01649 hInstance); 01650 } Generated on Sat May 26 2012 04:19:44 for ReactOS by
1.7.6.1
|