mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 18:54:25 +00:00
[User32]
- Patch by Katayama Hirofumi MZ : Improve task switcher's appearance. - Debugged Alt+Esc - Pixel perfect - Implemented "Display Item Shifting" - Added comments. svn path=/trunk/; revision=73332
This commit is contained in:
parent
ff16e0a2fc
commit
4027329c6a
|
@ -5,13 +5,37 @@
|
|||
* PURPOSE: app switching functionality
|
||||
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||
* David Quintana (gigaherz@gmail.com)
|
||||
* Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// Move to Win32k.
|
||||
// Add registry support.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include <user32.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
||||
|
||||
#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 // margin height around text
|
||||
|
||||
// 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
|
||||
|
@ -35,28 +59,74 @@ int nItems, nCols, nRows;
|
|||
int itemsW, itemsH;
|
||||
int totalW, totalH;
|
||||
int xOffset, yOffset;
|
||||
POINT pt;
|
||||
POINT ptStart;
|
||||
|
||||
int nShift = 0;
|
||||
|
||||
BOOL Esc = FALSE;
|
||||
|
||||
BOOL CoolSwitch = TRUE;
|
||||
int CoolSwitchRows = 3;
|
||||
int CoolSwitchColumns = 7;
|
||||
|
||||
// window style
|
||||
const DWORD Style = WS_POPUP | WS_BORDER | WS_DISABLED;
|
||||
const DWORD ExStyle = WS_EX_TOPMOST | WS_EX_DLGMODALFRAME | WS_EX_TOOLWINDOW;
|
||||
|
||||
DWORD wtodw(const WCHAR *psz)
|
||||
{
|
||||
const WCHAR *pch = psz;
|
||||
DWORD Value = 0;
|
||||
while ('0' <= *pch && *pch <= '9')
|
||||
{
|
||||
Value *= 10;
|
||||
Value += *pch - L'0';
|
||||
}
|
||||
return Value;
|
||||
}
|
||||
|
||||
BOOL LoadCoolSwitchSettings(void)
|
||||
{
|
||||
CoolSwitch = TRUE;
|
||||
CoolSwitchRows = 3;
|
||||
CoolSwitchColumns = 7;
|
||||
|
||||
// FIXME: load the settings from registry
|
||||
|
||||
TRACE("CoolSwitch: %d\n", CoolSwitch);
|
||||
TRACE("CoolSwitchRows: %d\n", CoolSwitchRows);
|
||||
TRACE("CoolSwitchColumns: %d\n", CoolSwitchColumns);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ResizeAndCenter(HWND hwnd, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
RECT Rect;
|
||||
|
||||
int screenwidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
int screenheight = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
pt.x = (screenwidth - width) / 2;
|
||||
pt.y = (screenheight - height) / 2;
|
||||
x = (screenwidth - width) / 2;
|
||||
y = (screenheight - height) / 2;
|
||||
|
||||
MoveWindow(hwnd, pt.x, pt.y, width, height, FALSE);
|
||||
SetRect(&Rect, x, y, x + width, y + height);
|
||||
AdjustWindowRectEx(&Rect, Style, FALSE, ExStyle);
|
||||
|
||||
x = Rect.left;
|
||||
y = Rect.top;
|
||||
width = Rect.right - Rect.left;
|
||||
height = Rect.bottom - Rect.top;
|
||||
MoveWindow(hwnd, x, y, width, height, FALSE);
|
||||
|
||||
ptStart.x = x;
|
||||
ptStart.y = y;
|
||||
}
|
||||
|
||||
void MakeWindowActive(HWND hwnd)
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
|
||||
wpl.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(hwnd, &wpl);
|
||||
|
||||
TRACE("GetWindowPlacement wpl.showCmd %d\n",wpl.showCmd);
|
||||
if (wpl.showCmd == SW_SHOWMINIMIZED)
|
||||
if (IsIconic(hwnd))
|
||||
ShowWindowAsync(hwnd, SW_RESTORE);
|
||||
|
||||
BringWindowToTop(hwnd); // same as: SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); ?
|
||||
|
@ -139,7 +209,7 @@ BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam)
|
|||
|
||||
// If we got to the max number of windows,
|
||||
// we won't be able to add any more
|
||||
if(windowCount == MAX_WINDOWS)
|
||||
if(windowCount >= MAX_WINDOWS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -164,17 +234,14 @@ void ProcessMouseMessage(UINT message, LPARAM lParam)
|
|||
int xPos = LOWORD(lParam);
|
||||
int yPos = HIWORD(lParam);
|
||||
|
||||
int xIndex = (xPos - xOffset)/40;
|
||||
int xOff = (xPos - xOffset)%40;
|
||||
int xIndex = (xPos - DIALOG_MARGIN) / CX_ITEM_SPACE;
|
||||
int yIndex = (yPos - DIALOG_MARGIN) / CY_ITEM_SPACE;
|
||||
|
||||
int yIndex = (yPos - yOffset)/40;
|
||||
int yOff = (yPos - yOffset)%40;
|
||||
|
||||
if(xOff > 32 || xIndex > nItems)
|
||||
return;
|
||||
|
||||
if(yOff > 32 || yIndex > nRows)
|
||||
return;
|
||||
if (xIndex < 0 || nCols <= xIndex ||
|
||||
yIndex < 0 || nRows <= yIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
selectedWindow = (yIndex*nCols) + xIndex;
|
||||
if (message == WM_MOUSEMOVE)
|
||||
|
@ -191,63 +258,95 @@ void ProcessMouseMessage(UINT message, LPARAM lParam)
|
|||
|
||||
void OnPaint(HWND hWnd)
|
||||
{
|
||||
HDC dialogDC;
|
||||
PAINTSTRUCT paint;
|
||||
RECT cRC, textRC;
|
||||
int i;
|
||||
HBRUSH hBrush;
|
||||
HPEN hPen;
|
||||
HFONT dcFont;
|
||||
COLORREF cr;
|
||||
int nch = GetWindowTextW(windowList[selectedWindow], windowText, _countof(windowText));
|
||||
HDC dialogDC;
|
||||
PAINTSTRUCT paint;
|
||||
RECT cRC, textRC;
|
||||
int i, xPos, yPos, CharCount;
|
||||
HFONT dcFont;
|
||||
HICON hIcon;
|
||||
HPEN hPen;
|
||||
COLORREF Color;
|
||||
|
||||
dialogDC = BeginPaint(hWnd, &paint);
|
||||
{
|
||||
GetClientRect(hWnd, &cRC);
|
||||
FillRect(dialogDC, &cRC, GetSysColorBrush(COLOR_MENU));
|
||||
// check
|
||||
if (nCols == 0 || nItems == 0)
|
||||
return;
|
||||
|
||||
for(i=0; i< windowCount; i++)
|
||||
{
|
||||
HICON hIcon = iconList[i];
|
||||
// begin painting
|
||||
dialogDC = BeginPaint(hWnd, &paint);
|
||||
if (dialogDC == NULL)
|
||||
return;
|
||||
|
||||
int xpos = xOffset + 40 * (i % nCols);
|
||||
int ypos = yOffset + 40 * (i / nCols);
|
||||
// fill the client area
|
||||
GetClientRect(hWnd, &cRC);
|
||||
FillRect(dialogDC, &cRC, (HBRUSH)(COLOR_3DFACE + 1));
|
||||
|
||||
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);
|
||||
SelectObject(dialogDC, hPen);
|
||||
SelectObject(dialogDC, hBrush);
|
||||
Rectangle(dialogDC, xpos-2, ypos-2, xpos+32+2, ypos+32+2);
|
||||
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);
|
||||
}
|
||||
// if the selection index exceeded the display items, then
|
||||
// do display item shifting
|
||||
if (selectedWindow >= nItems)
|
||||
nShift = selectedWindow - nItems + 1;
|
||||
else
|
||||
nShift = 0;
|
||||
|
||||
dcFont = SelectObject(dialogDC, dialogFont);
|
||||
SetTextColor(dialogDC, GetSysColor(COLOR_BTNTEXT));
|
||||
SetBkMode(dialogDC, TRANSPARENT);
|
||||
for (i = 0; i < nItems; ++i)
|
||||
{
|
||||
// get the icon to display
|
||||
hIcon = iconList[i + nShift];
|
||||
|
||||
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);
|
||||
}
|
||||
EndPaint(hWnd, &paint);
|
||||
// calculate the position where we start drawing
|
||||
xPos = DIALOG_MARGIN + CX_ITEM_SPACE * (i % nCols) + ITEM_MARGIN;
|
||||
yPos = DIALOG_MARGIN + CY_ITEM_SPACE * (i / nCols) + ITEM_MARGIN;
|
||||
|
||||
// centering
|
||||
if (nItems < CoolSwitchColumns)
|
||||
{
|
||||
xPos += (itemsW - nItems * CX_ITEM_SPACE) / 2;
|
||||
}
|
||||
|
||||
// if this position is selected,
|
||||
if (selectedWindow == i + nShift)
|
||||
{
|
||||
// create a solid pen
|
||||
Color = GetSysColor(COLOR_HIGHLIGHT);
|
||||
hPen = CreatePen(PS_SOLID, 1, Color);
|
||||
|
||||
// draw a rectangle with using the pen
|
||||
SelectObject(dialogDC, hPen);
|
||||
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);
|
||||
}
|
||||
|
||||
// draw icon
|
||||
DrawIconEx(dialogDC, xPos + ICON_MARGIN, yPos + ICON_MARGIN,
|
||||
hIcon, CX_ICON, CY_ICON, 0, NULL, DI_NORMAL);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// end painting
|
||||
EndPaint(hWnd, &paint);
|
||||
}
|
||||
|
||||
DWORD CreateSwitcherWindow(HINSTANCE hInstance)
|
||||
|
@ -288,27 +387,23 @@ DWORD GetDialogFont(VOID)
|
|||
|
||||
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;
|
||||
|
||||
totalW = itemsW + 2*cxBorder + 4;
|
||||
totalH = itemsH + 2*cyBorder + fontHeight + 8; // give extra pixels for the window title
|
||||
|
||||
xOffset = 8;
|
||||
yOffset = 8;
|
||||
|
||||
if (nItems < nCols)
|
||||
nCols = CoolSwitchColumns;
|
||||
nRows = (nItems + CoolSwitchColumns - 1) / CoolSwitchColumns;
|
||||
if (nRows > CoolSwitchRows)
|
||||
{
|
||||
int w2 = nItems*32 + (nItems-1)*8;
|
||||
xOffset = (itemsW-w2)/2;
|
||||
nRows = CoolSwitchRows;
|
||||
nItems = nRows * nCols;
|
||||
}
|
||||
|
||||
itemsW = nCols * CX_ITEM_SPACE;
|
||||
itemsH = nRows * CY_ITEM_SPACE;
|
||||
|
||||
totalW = itemsW + 2 * DIALOG_MARGIN;
|
||||
totalH = itemsH + 2 * DIALOG_MARGIN;
|
||||
totalH += fontHeight + 2 * CY_TEXT_MARGIN;
|
||||
|
||||
ResizeAndCenter(switchdialog, totalW, totalH);
|
||||
}
|
||||
|
||||
|
@ -338,20 +433,95 @@ BOOL ProcessHotKey(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void RotateTasks(BOOL bShift)
|
||||
{
|
||||
HWND hwndFirst, hwndLast;
|
||||
DWORD Size;
|
||||
|
||||
if (windowCount < 2 || !Esc)
|
||||
return;
|
||||
|
||||
hwndFirst = windowList[0];
|
||||
hwndLast = windowList[windowCount - 1];
|
||||
|
||||
if (bShift)
|
||||
{
|
||||
SetWindowPos(hwndLast, HWND_TOP, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
||||
SWP_NOOWNERZORDER | SWP_NOREPOSITION);
|
||||
|
||||
MakeWindowActive(hwndLast);
|
||||
|
||||
Size = (windowCount - 1) * sizeof(HWND);
|
||||
MoveMemory(&windowList[1], &windowList[0], Size);
|
||||
windowList[0] = hwndLast;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos(hwndFirst, hwndLast, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
||||
SWP_NOOWNERZORDER | SWP_NOREPOSITION);
|
||||
|
||||
MakeWindowActive(windowList[1]);
|
||||
|
||||
Size = (windowCount - 1) * sizeof(HWND);
|
||||
MoveMemory(&windowList[0], &windowList[1], Size);
|
||||
windowList[windowCount - 1] = hwndFirst;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
DestroyAppWindows(VOID)
|
||||
{
|
||||
// for every item of the icon list:
|
||||
INT i;
|
||||
for (i = 0; i < windowCount; ++i)
|
||||
{
|
||||
// destroy the icon
|
||||
DestroyIcon(iconList[i]);
|
||||
iconList[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
HWND hwnd, hwndActive;
|
||||
HWND hwndActive;
|
||||
MSG msg;
|
||||
BOOL Esc = FALSE;
|
||||
INT Count = 0;
|
||||
WCHAR Text[1024];
|
||||
|
||||
// FIXME: Is loading timing OK?
|
||||
LoadCoolSwitchSettings();
|
||||
|
||||
if (!CoolSwitch)
|
||||
return 0;
|
||||
|
||||
// Already in the loop.
|
||||
if (switchdialog) return 0;
|
||||
if (switchdialog || Esc) return 0;
|
||||
|
||||
hwndActive = GetActiveWindow();
|
||||
// Nothing is active so exit.
|
||||
if (!hwndActive) return 0;
|
||||
|
||||
if (lParam == VK_ESCAPE)
|
||||
{
|
||||
Esc = TRUE;
|
||||
|
||||
windowCount = 0;
|
||||
EnumWindowsZOrder(EnumerateCallback, 0);
|
||||
|
||||
if (windowCount < 2)
|
||||
return 0;
|
||||
|
||||
RotateTasks(GetAsyncKeyState(VK_SHIFT) < 0);
|
||||
|
||||
hwndActive = GetActiveWindow();
|
||||
|
||||
if (hwndActive == NULL)
|
||||
{
|
||||
Esc = FALSE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Capture current active window.
|
||||
SetCapture( hwndActive );
|
||||
|
||||
|
@ -364,25 +534,6 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
|
|||
break;
|
||||
|
||||
case VK_ESCAPE:
|
||||
windowCount = 0;
|
||||
Count = 0;
|
||||
EnumWindowsZOrder(EnumerateCallback, 0);
|
||||
if (windowCount < 2) goto Exit;
|
||||
if (wParam == SC_NEXTWINDOW)
|
||||
Count = 1;
|
||||
else
|
||||
{
|
||||
if (windowCount == 2)
|
||||
Count = 0;
|
||||
else
|
||||
Count = windowCount - 1;
|
||||
}
|
||||
TRACE("DoAppSwitch VK_ESCAPE 1 Count %d windowCount %d\n",Count,windowCount);
|
||||
hwnd = windowList[Count];
|
||||
GetWindowTextW(hwnd, Text, _countof(Text));
|
||||
TRACE("[ATbot] Switching to 0x%08x (%ls)\n", hwnd, Text);
|
||||
MakeWindowActive(hwnd);
|
||||
Esc = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -429,41 +580,25 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
|
|||
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
|
||||
if (HIWORD(msg.lParam) & KF_ALTDOWN)
|
||||
{
|
||||
INT Shift;
|
||||
if ( msg.wParam == VK_TAB )
|
||||
{
|
||||
if (Esc) break;
|
||||
Shift = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
|
||||
if (Shift == SC_NEXTWINDOW)
|
||||
{
|
||||
selectedWindow = (selectedWindow + 1)%windowCount;
|
||||
}
|
||||
else
|
||||
if (GetKeyState(VK_SHIFT) < 0)
|
||||
{
|
||||
selectedWindow = selectedWindow - 1;
|
||||
if (selectedWindow < 0)
|
||||
selectedWindow = windowCount - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedWindow = (selectedWindow + 1)%windowCount;
|
||||
}
|
||||
InvalidateRect(switchdialog, NULL, TRUE);
|
||||
}
|
||||
else if ( msg.wParam == VK_ESCAPE )
|
||||
{
|
||||
if (!Esc) break;
|
||||
if (windowCount < 2)
|
||||
goto Exit;
|
||||
if (wParam == SC_NEXTWINDOW)
|
||||
{
|
||||
Count = (Count + 1)%windowCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Count--;
|
||||
if (Count < 0)
|
||||
Count = windowCount - 1;
|
||||
}
|
||||
hwnd = windowList[Count];
|
||||
GetWindowTextW(hwnd, Text, _countof(Text));
|
||||
MakeWindowActive(hwnd);
|
||||
RotateTasks(GetKeyState(VK_SHIFT) < 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -486,23 +621,14 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
|
|||
Exit:
|
||||
ReleaseCapture();
|
||||
if (switchdialog) DestroyWindow(switchdialog);
|
||||
if (Esc) DestroyAppWindows();
|
||||
switchdialog = NULL;
|
||||
selectedWindow = 0;
|
||||
windowCount = 0;
|
||||
Esc = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
DestroyAppWindows(VOID)
|
||||
{
|
||||
INT i;
|
||||
for (i=0; i< windowCount; i++)
|
||||
{
|
||||
HICON hIcon = iconList[i];
|
||||
DestroyIcon(hIcon);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Switch System Class Window Proc.
|
||||
//
|
||||
|
@ -532,10 +658,23 @@ LRESULT WINAPI SwitchWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||
{
|
||||
PrepareWindow();
|
||||
ati = (PALTTABINFO)GetWindowLongPtrW(hWnd, 0);
|
||||
ati->cbSize = sizeof(ALTTABINFO);
|
||||
ati->cItems = nItems;
|
||||
ati->cxItem = ati->cyItem = 43;
|
||||
ati->cRows = nRows;
|
||||
ati->cColumns = nCols;
|
||||
ati->cRows = nRows;
|
||||
if (nCols)
|
||||
{
|
||||
ati->iColFocus = (selectedWindow - nShift) % nCols;
|
||||
ati->iRowFocus = (selectedWindow - nShift) / nCols;
|
||||
}
|
||||
else
|
||||
{
|
||||
ati->iColFocus = 0;
|
||||
ati->iRowFocus = 0;
|
||||
}
|
||||
ati->cxItem = CX_ITEM_SPACE;
|
||||
ati->cyItem = CY_ITEM_SPACE;
|
||||
ati->ptStart = ptStart;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue