Index: reactos/win32ss/user/user32/controls/appswitch.c =================================================================== --- reactos/win32ss/user/user32/controls/appswitch.c (revision 72934) +++ reactos/win32ss/user/user32/controls/appswitch.c (working copy) @@ -5,6 +5,7 @@ * PURPOSE: app switching functionality * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) * David Quintana (gigaherz@gmail.com) + * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) */ #include @@ -12,6 +13,28 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(user32); +// FIXME: behavior of Alt+Esc is wrong +// FIXME: frequent Alt+Esc can cause system crash + +#define DIALOG_MARGIN 8 // margin of dialog contents + +#define CX_ICON 32 // width of icon +#define CY_ICON 32 // height of icon +#define ICON_MARGIN 4 // margin width around an icon + +#define CX_ITEM (CX_ICON + 2 * ICON_MARGIN) +#define CY_ITEM (CY_ICON + 2 * ICON_MARGIN) +#define ITEM_MARGIN 4 // margin width around an item + +#define CX_ITEM_SPACE (CX_ITEM + 2 * ITEM_MARGIN) +#define CY_ITEM_SPACE (CY_ITEM + 2 * ITEM_MARGIN) + +#define CY_TEXT_MARGIN 4 + +#define MIN_COLUMNS 8 +#define MAX_COLUMNS 12 +#define MAX_ROWS 10 + // limit the number of windows shown in the alt-tab window // 120 windows results in (12*40) by (10*40) pixels worth of icons. #define MAX_WINDOWS 120 @@ -42,6 +65,11 @@ int screenwidth = GetSystemMetrics(SM_CXSCREEN); int screenheight = GetSystemMetrics(SM_CYSCREEN); + int cxBorder = GetSystemMetrics(SM_CXBORDER); + int cyBorder = GetSystemMetrics(SM_CYBORDER); + width += cxBorder * 2; + height += cyBorder * 2; + pt.x = (screenwidth - width) / 2; pt.y = (screenheight - height) / 2; @@ -78,8 +106,6 @@ if(selectedWindow >= windowCount) return; - // FIXME: workaround because reactos fails to activate the previous window correctly. - //if(selectedWindow != 0) { HWND hwnd = windowList[selectedWindow]; @@ -194,59 +220,71 @@ HDC dialogDC; PAINTSTRUCT paint; RECT cRC, textRC; - int i; - HBRUSH hBrush; - HPEN hPen; + int i, xPos, yPos, CharCount; HFONT dcFont; - COLORREF cr; - int nch = GetWindowTextW(windowList[selectedWindow], windowText, _countof(windowText)); dialogDC = BeginPaint(hWnd, &paint); + if (dialogDC == NULL) + return; + + GetClientRect(hWnd, &cRC); + FillRect(dialogDC, &cRC, (HBRUSH)(COLOR_3DFACE + 1)); + + for (i = 0; i < nItems; ++i) { - GetClientRect(hWnd, &cRC); - FillRect(dialogDC, &cRC, GetSysColorBrush(COLOR_MENU)); + HICON hIcon = iconList[i]; + xPos = DIALOG_MARGIN + CX_ITEM_SPACE * (i % nCols) + ITEM_MARGIN; + yPos = DIALOG_MARGIN + CY_ITEM_SPACE * (i / nCols) + ITEM_MARGIN; - for(i=0; i< windowCount; i++) + // centering + if (nItems < MIN_COLUMNS) { - HICON hIcon = iconList[i]; + xPos += (itemsW - nItems * CX_ITEM_SPACE) / 2; + } - int xpos = xOffset + 40 * (i % nCols); - int ypos = yOffset + 40 * (i / nCols); + if (selectedWindow == i) + { + COLORREF Color = GetSysColor(COLOR_HIGHLIGHT); - if (selectedWindow == i) - { - hBrush = GetSysColorBrush(COLOR_HIGHLIGHT); - } - else - { - hBrush = GetSysColorBrush(COLOR_MENU); - } -#if TRUE - cr = GetSysColor(COLOR_BTNTEXT); // doesn't look right! >_< - hPen = CreatePen(PS_DOT, 1, cr); + // create a solid pen + HPEN hPen = CreatePen(PS_SOLID, 1, Color); + + // draw a rectangle with using the pen SelectObject(dialogDC, hPen); - SelectObject(dialogDC, hBrush); - Rectangle(dialogDC, xpos-2, ypos-2, xpos+32+2, ypos+32+2); + SelectObject(dialogDC, GetStockObject(NULL_BRUSH)); + Rectangle(dialogDC, xPos, yPos, xPos + CX_ITEM, yPos + CY_ITEM); + Rectangle(dialogDC, xPos + 1, yPos + 1, + xPos + CX_ITEM - 1, yPos + CY_ITEM - 1); + + // delete the pen DeleteObject(hPen); - // Must NOT destroy the system brush! -#else - RECT rc = { xpos-2, ypos-2, xpos+32+2, ypos+32+2 }; - FillRect(dialogDC, &rc, hBrush); -#endif - DrawIcon(dialogDC, xpos, ypos, hIcon); } - dcFont = SelectObject(dialogDC, dialogFont); - SetTextColor(dialogDC, GetSysColor(COLOR_BTNTEXT)); - SetBkMode(dialogDC, TRANSPARENT); + // draw icon + DrawIconEx(dialogDC, xPos + ICON_MARGIN, yPos + ICON_MARGIN, + hIcon, CX_ICON, CY_ICON, 0, NULL, DI_NORMAL); + } - textRC.top = itemsH; - textRC.left = 8; - textRC.right = totalW - 8; - textRC.bottom = totalH - 8; - DrawTextW(dialogDC, windowText, nch, &textRC, DT_CENTER|DT_END_ELLIPSIS); - SelectObject(dialogDC, dcFont); - } + // set the text rectangle + SetRect(&textRC, DIALOG_MARGIN, DIALOG_MARGIN + itemsH, + totalW - DIALOG_MARGIN, totalH - DIALOG_MARGIN); + + // draw the sunken button around text + DrawFrameControl(dialogDC, &textRC, DFC_BUTTON, + DFCS_BUTTONPUSH | DFCS_PUSHED); + + // get text + CharCount = GetWindowTextW(windowList[selectedWindow], windowText, + _countof(windowText)); + + // draw text + dcFont = SelectObject(dialogDC, dialogFont); + SetTextColor(dialogDC, GetSysColor(COLOR_BTNTEXT)); + SetBkMode(dialogDC, TRANSPARENT); + DrawTextW(dialogDC, windowText, CharCount, &textRC, + DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE); + SelectObject(dialogDC, dcFont); + EndPaint(hWnd, &paint); } @@ -288,27 +326,28 @@ void PrepareWindow(VOID) { - cxBorder = GetSystemMetrics(SM_CXBORDER); - cyBorder = GetSystemMetrics(SM_CYBORDER); - nItems = windowCount; - nCols = min(max(nItems,8),12); - nRows = (nItems+nCols-1)/nCols; - itemsW = nCols*32 + (nCols+1)*8; - itemsH = nRows*32 + (nRows+1)*8; + nCols = nItems; + if (nCols < MIN_COLUMNS) + nCols = MIN_COLUMNS; + if (nCols > MAX_COLUMNS) + nCols = MAX_COLUMNS; - totalW = itemsW + 2*cxBorder + 4; - totalH = itemsH + 2*cyBorder + fontHeight + 8; // give extra pixels for the window title + nRows = (nItems + MAX_COLUMNS - 1) / MAX_COLUMNS; + if (nRows > MAX_ROWS) + { + nRows = MAX_ROWS; + nItems = nRows * nCols; + } - xOffset = 8; - yOffset = 8; + itemsW = nCols * CX_ITEM_SPACE; + itemsH = nRows * CY_ITEM_SPACE; - if (nItems < nCols) - { - int w2 = nItems*32 + (nItems-1)*8; - xOffset = (itemsW-w2)/2; - } + totalW = itemsW + 2 * DIALOG_MARGIN; + totalH = itemsH + 2 * DIALOG_MARGIN; + totalH += fontHeight + 2 * CY_TEXT_MARGIN; + ResizeAndCenter(switchdialog, totalW, totalH); } @@ -433,7 +472,7 @@ if ( msg.wParam == VK_TAB ) { if (Esc) break; - Shift = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; + Shift = GetKeyState(VK_SHIFT) < 0 ? SC_PREVWINDOW : SC_NEXTWINDOW; if (Shift == SC_NEXTWINDOW) { selectedWindow = (selectedWindow + 1)%windowCount; @@ -448,7 +487,8 @@ } else if ( msg.wParam == VK_ESCAPE ) { - if (!Esc) break; + if (!Esc) + goto Exit; if (windowCount < 2) goto Exit; if (wParam == SC_NEXTWINDOW) @@ -493,7 +533,7 @@ } VOID -DestroyAppWindows(VOID) +DestroyAppIcons(VOID) { INT i; for (i=0; i< windowCount; i++) @@ -533,7 +573,8 @@ PrepareWindow(); ati = (PALTTABINFO)GetWindowLongPtrW(hWnd, 0); ati->cItems = nItems; - ati->cxItem = ati->cyItem = 43; + ati->cxItem = CX_ITEM; + ati->cyItem = CY_ITEM; ati->cRows = nRows; ati->cColumns = nCols; } @@ -559,11 +600,14 @@ ati = (PALTTABINFO)GetWindowLongPtrW(hWnd, 0); HeapFree( GetProcessHeap(), 0, ati ); SetWindowLongPtrW( hWnd, 0, 0 ); - DestroyAppWindows(); + DestroyAppIcons(); NtUserSetWindowFNID(hWnd, FNID_DESTROY); return 0; } - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + if (unicode) + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + else + return DefWindowProcA(hWnd, uMsg, wParam, lParam); } LRESULT WINAPI SwitchWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)