📄 mdi.c
字号:
}
return DefWindowProcW(hwnd, message, wParam, lParam);
}
/**********************************************************************
* CreateMDIWindowA (USER32.@) Creates a MDI child
*
* RETURNS
* Success: Handle to created window
* Failure: NULL
*/
HWND WINAPI CreateMDIWindowA(
LPCSTR lpClassName, /* [in] Pointer to registered child class name */
LPCSTR lpWindowName, /* [in] Pointer to window name */
DWORD dwStyle, /* [in] Window style */
INT X, /* [in] Horizontal position of window */
INT Y, /* [in] Vertical position of window */
INT nWidth, /* [in] Width of window */
INT nHeight, /* [in] Height of window */
HWND hWndParent, /* [in] Handle to parent window */
HINSTANCE hInstance, /* [in] Handle to application instance */
LPARAM lParam) /* [in] Application-defined value */
{
TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
nWidth,nHeight,hWndParent,hInstance,lParam);
return CreateWindowExA(WS_EX_MDICHILD, lpClassName, lpWindowName,
dwStyle, X, Y, nWidth, nHeight, hWndParent,
0, hInstance, (LPVOID)lParam);
}
/***********************************************************************
* CreateMDIWindowW (USER32.@) Creates a MDI child
*
* RETURNS
* Success: Handle to created window
* Failure: NULL
*/
HWND WINAPI CreateMDIWindowW(
LPCWSTR lpClassName, /* [in] Pointer to registered child class name */
LPCWSTR lpWindowName, /* [in] Pointer to window name */
DWORD dwStyle, /* [in] Window style */
INT X, /* [in] Horizontal position of window */
INT Y, /* [in] Vertical position of window */
INT nWidth, /* [in] Width of window */
INT nHeight, /* [in] Height of window */
HWND hWndParent, /* [in] Handle to parent window */
HINSTANCE hInstance, /* [in] Handle to application instance */
LPARAM lParam) /* [in] Application-defined value */
{
TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
nWidth, nHeight, hWndParent, hInstance, lParam);
return CreateWindowExW(WS_EX_MDICHILD, lpClassName, lpWindowName,
dwStyle, X, Y, nWidth, nHeight, hWndParent,
0, hInstance, (LPVOID)lParam);
}
/**********************************************************************
* TranslateMDISysAccel (USER32.@)
*/
BOOL WINAPI TranslateMDISysAccel( HWND hwndClient, LPMSG msg )
{
if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
{
MDICLIENTINFO *ci = get_client_info( hwndClient );
WPARAM wParam = 0;
if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
/* translate if the Ctrl key is down and Alt not. */
if( (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
{
switch( msg->wParam )
{
case VK_F6:
case VK_TAB:
wParam = ( GetKeyState(VK_SHIFT) & 0x8000 ) ? SC_NEXTWINDOW : SC_PREVWINDOW;
break;
case VK_F4:
case VK_RBUTTON:
if (is_close_enabled(ci->hwndActiveChild, 0))
{
wParam = SC_CLOSE;
break;
}
/* fall through */
default:
return 0;
}
TRACE("wParam = %04x\n", wParam);
SendMessageW(ci->hwndActiveChild, WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
return 1;
}
}
return 0; /* failure */
}
/***********************************************************************
* CalcChildScroll (USER32.@)
*/
void WINAPI CalcChildScroll( HWND hwnd, INT scroll )
{
SCROLLINFO info;
RECT childRect, clientRect;
HWND *list;
WINDOWINFO WindowInfo;
GetClientRect( hwnd, &clientRect );
SetRectEmpty( &childRect );
/* The rectangle returned by GetClientRect always has 0,0 as top left
* because it is in client coordinates. The rectangles returned by
* GetWindowRect are in screen coordinates to make this complicated.
*
* Apparently (in ReactOS at least) the rcClient returned by GetWindowInfo
* is in screen coordinates too.
*/
WindowInfo.cbSize = sizeof(WindowInfo);
if (!GetWindowInfo(hwnd, &WindowInfo))
{
ERR("Can't get window info\n");
return;
}
if ((list = WIN_ListChildren( hwnd )))
{
int i;
for (i = 0; list[i]; i++)
{
DWORD style = GetWindowLongW( list[i], GWL_STYLE );
if (style & WS_MAXIMIZE)
{
HeapFree( GetProcessHeap(), 0, list );
ShowScrollBar( hwnd, SB_BOTH, FALSE );
return;
}
if (style & WS_VISIBLE)
{
RECT rect;
GetWindowRect( list[i], &rect );
OffsetRect(&rect, -WindowInfo.rcClient.left,
-WindowInfo.rcClient.top);
UnionRect( &childRect, &rect, &childRect );
}
}
HeapFree( GetProcessHeap(), 0, list );
}
MapWindowPoints( 0, hwnd, (POINT *)&childRect, 2 );
UnionRect( &childRect, &clientRect, &childRect );
/* set common info values */
info.cbSize = sizeof(info);
info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
/* set the specific */
/* Note how we set nPos to 0 because we scroll the clients instead of
* the window, and we set nPage to 1 bigger than the clientRect because
* otherwise the scrollbar never disables. This causes a somewhat ugly
* effect though while scrolling.
*/
switch( scroll )
{
case SB_BOTH:
case SB_HORZ:
info.nMin = childRect.left;
info.nMax = childRect.right;
info.nPos = 0;
info.nPage = 1 + clientRect.right - clientRect.left;
SetScrollInfo(hwnd, SB_HORZ, &info, TRUE);
if (scroll == SB_HORZ) break;
/* fall through */
case SB_VERT:
info.nMin = childRect.top;
info.nMax = childRect.bottom;
info.nPos = 0;
info.nPage = 1 + clientRect.bottom - clientRect.top;
SetScrollInfo(hwnd, SB_VERT, &info, TRUE);
break;
}
}
/***********************************************************************
* ScrollChildren (USER32.@)
*/
void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
INT newPos = -1;
INT curPos, length, minPos, maxPos, shift;
RECT rect;
GetClientRect( hWnd, &rect );
switch(uMsg)
{
case WM_HSCROLL:
GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
curPos = GetScrollPos(hWnd,SB_HORZ);
length = (rect.right - rect.left) / 2;
shift = GetSystemMetrics(SM_CYHSCROLL);
break;
case WM_VSCROLL:
GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
curPos = GetScrollPos(hWnd,SB_VERT);
length = (rect.bottom - rect.top) / 2;
shift = GetSystemMetrics(SM_CXVSCROLL);
break;
default:
return;
}
switch( wParam )
{
case SB_LINEUP:
newPos = curPos - shift;
break;
case SB_LINEDOWN:
newPos = curPos + shift;
break;
case SB_PAGEUP:
newPos = curPos - length;
break;
case SB_PAGEDOWN:
newPos = curPos + length;
break;
case SB_THUMBPOSITION:
newPos = LOWORD(lParam);
break;
case SB_THUMBTRACK:
return;
case SB_TOP:
newPos = minPos;
break;
case SB_BOTTOM:
newPos = maxPos;
break;
case SB_ENDSCROLL:
CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
return;
}
if( newPos > maxPos )
newPos = maxPos;
else
if( newPos < minPos )
newPos = minPos;
SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
if( uMsg == WM_VSCROLL )
ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
else
ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
}
/******************************************************************************
* CascadeWindows (USER32.@) Cascades MDI child windows
*
* RETURNS
* Success: Number of cascaded windows.
* Failure: 0
*/
WORD WINAPI
CascadeWindows (HWND hwndParent, UINT wFlags, LPCRECT lpRect,
UINT cKids, const HWND *lpKids)
{
FIXME("(%p,0x%08x,...,%u,...): stub\n", hwndParent, wFlags, cKids);
return 0;
}
/******************************************************************************
* TileWindows (USER32.@) Tiles MDI child windows
*
* RETURNS
* Success: Number of tiled windows.
* Failure: 0
*/
WORD WINAPI
TileWindows (HWND hwndParent, UINT wFlags, LPCRECT lpRect,
UINT cKids, const HWND *lpKids)
{
FIXME("(%p,0x%08x,...,%u,...): stub\n", hwndParent, wFlags, cKids);
return 0;
}
/************************************************************************
* "More Windows..." functionality
*/
/* MDI_MoreWindowsDlgProc
*
* This function will process the messages sent to the "More Windows..."
* dialog.
* Return values: 0 = cancel pressed
* HWND = ok pressed or double-click in the list...
*
*/
static INT_PTR WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_INITDIALOG:
{
UINT widest = 0;
UINT length;
UINT i;
MDICLIENTINFO *ci = get_client_info( (HWND)lParam );
HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
for (i = 0; i < ci->nActiveChildren; i++)
{
WCHAR buffer[MDI_MAXTITLELENGTH];
if (!InternalGetWindowText( ci->child[i], buffer, sizeof(buffer)/sizeof(WCHAR) ))
continue;
SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM)buffer );
SendMessageW(hListBox, LB_SETITEMDATA, i, (LPARAM)ci->child[i] );
length = strlenW(buffer); /* FIXME: should use GetTextExtentPoint */
if (length > widest)
widest = length;
}
/* Make sure the horizontal scrollbar scrolls ok */
SendMessageW(hListBox, LB_SETHORIZONTALEXTENT, widest * 6, 0);
/* Set the current selection */
SendMessageW(hListBox, LB_SETCURSEL, MDI_MOREWINDOWSLIMIT, 0);
return TRUE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
default:
if (HIWORD(wParam) != LBN_DBLCLK) break;
/* fall through */
case IDOK:
{
/* windows are sorted by menu ID, so we must return the
* window associated to the given id
*/
HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
UINT index = SendMessageW(hListBox, LB_GETCURSEL, 0, 0);
LRESULT res = SendMessageW(hListBox, LB_GETITEMDATA, index, 0);
EndDialog(hDlg, res);
return TRUE;
}
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}
/*
*
* MDI_MoreWindowsDialog
*
* Prompts the user with a listbox containing the opened
* documents. The user can then choose a windows and click
* on OK to set the current window to the one selected, or
* CANCEL to cancel. The function returns a handle to the
* selected window.
*/
static HWND MDI_MoreWindowsDialog(HWND hwnd)
{
LPCVOID template;
HRSRC hRes;
HANDLE hDlgTmpl;
hRes = FindResourceA(User32Instance, "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
if (hRes == 0)
return 0;
hDlgTmpl = LoadResource(User32Instance, hRes );
if (hDlgTmpl == 0)
return 0;
template = LockResource( hDlgTmpl );
if (template == 0)
return 0;
return (HWND) DialogBoxIndirectParamA(User32Instance,
(const DLGTEMPLATE*) template,
hwnd, MDI_MoreWindowsDlgProc, (LPARAM) hwnd);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -