ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

monslctl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.