📄 status.c
字号:
infoPtr->parts[0].text = 0;
infoPtr->parts[0].x = -1;
infoPtr->parts[0].style = 0;
infoPtr->parts[0].hIcon = 0;
OpenThemeData (hwnd, themeClass);
if (IsWindowUnicode (hwnd)) {
infoPtr->bUnicode = TRUE;
if (lpCreate->lpszName &&
(len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
infoPtr->parts[0].text = Alloc ((len + 1)*sizeof(WCHAR));
if (!infoPtr->parts[0].text) goto create_fail;
strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
}
}
else {
if (lpCreate->lpszName &&
(len = strlen((LPCSTR)lpCreate->lpszName))) {
DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
infoPtr->parts[0].text = Alloc (lenW*sizeof(WCHAR));
if (!infoPtr->parts[0].text) goto create_fail;
MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
infoPtr->parts[0].text, lenW );
}
}
dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
/* native seems to clear WS_BORDER, too */
dwStyle &= ~WS_BORDER;
/* statusbars on managed windows should not have SIZEGRIP style */
if ((dwStyle & SBARS_SIZEGRIP) && lpCreate->hwndParent &&
GetPropA( lpCreate->hwndParent, "__wine_x11_managed" ))
dwStyle &= ~SBARS_SIZEGRIP;
SetWindowLongW (hwnd, GWL_STYLE, dwStyle);
if ((hdc = GetDC (hwnd))) {
TEXTMETRICW tm;
HFONT hOldFont;
hOldFont = SelectObject (hdc, infoPtr->hDefaultFont);
GetTextMetricsW (hdc, &tm);
textHeight = tm.tmHeight;
SelectObject (hdc, hOldFont);
ReleaseDC (hwnd, hdc);
}
TRACE(" textHeight=%d\n", textHeight);
if (dwStyle & SBT_TOOLTIPS) {
infoPtr->hwndToolTip =
CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, WS_POPUP | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, hwnd, 0,
(HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), NULL);
if (infoPtr->hwndToolTip) {
NMTOOLTIPSCREATED nmttc;
nmttc.hdr.hwndFrom = hwnd;
nmttc.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmttc.hdr.code = NM_TOOLTIPSCREATED;
nmttc.hwndToolTips = infoPtr->hwndToolTip;
SendMessageW (lpCreate->hwndParent, WM_NOTIFY,
(WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
}
}
if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */
HTHEME theme;
GetClientRect (infoPtr->Notify, &rect);
width = rect.right - rect.left;
infoPtr->height = textHeight + 4 + infoPtr->verticalBorder;
if ((theme = GetWindowTheme (hwnd)))
{
/* Determine bar height from theme such that the content area is
* textHeight pixels large */
HDC hdc = GetDC (hwnd);
RECT r;
memset (&r, 0, sizeof (r));
r.bottom = textHeight;
if (SUCCEEDED(GetThemeBackgroundExtent (theme, hdc, SP_PANE, 0, &r, &r)))
{
infoPtr->height = r.bottom - r.top;
}
ReleaseDC (hwnd, hdc);
}
SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1,
width, infoPtr->height, SWP_NOZORDER);
STATUSBAR_SetPartBounds (infoPtr);
}
return 0;
create_fail:
TRACE(" failed!\n");
if (infoPtr) STATUSBAR_WMDestroy(infoPtr);
return -1;
}
/* in contrast to SB_GETTEXT*, WM_GETTEXT handles the text
* of the first part only (usual behaviour) */
static INT
STATUSBAR_WMGetText (STATUS_INFO *infoPtr, INT size, LPWSTR buf)
{
INT len;
TRACE("\n");
if (!(infoPtr->parts[0].text))
return 0;
if (infoPtr->bUnicode)
len = strlenW (infoPtr->parts[0].text);
else
len = WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1, NULL, 0, NULL, NULL )-1;
if (size > len) {
if (infoPtr->bUnicode)
strcpyW (buf, infoPtr->parts[0].text);
else
WideCharToMultiByte( CP_ACP, 0, infoPtr->parts[0].text, -1,
(LPSTR)buf, len+1, NULL, NULL );
return len;
}
return -1;
}
static BOOL
STATUSBAR_WMNCHitTest (STATUS_INFO *infoPtr, INT x, INT y)
{
if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) {
RECT rect;
POINT pt;
GetClientRect (infoPtr->Self, &rect);
pt.x = x;
pt.y = y;
ScreenToClient (infoPtr->Self, &pt);
rect.left = rect.right - 13;
rect.top += 2;
if (PtInRect (&rect, pt))
return HTBOTTOMRIGHT;
}
return HTERROR;
}
static LRESULT
STATUSBAR_WMPaint (STATUS_INFO *infoPtr, HDC hdc)
{
PAINTSTRUCT ps;
TRACE("\n");
if (hdc) return STATUSBAR_Refresh (infoPtr, hdc);
hdc = BeginPaint (infoPtr->Self, &ps);
STATUSBAR_Refresh (infoPtr, hdc);
EndPaint (infoPtr->Self, &ps);
return 0;
}
static LRESULT
STATUSBAR_WMSetFont (STATUS_INFO *infoPtr, HFONT font, BOOL redraw)
{
infoPtr->hFont = font;
TRACE("%p\n", infoPtr->hFont);
if (redraw)
InvalidateRect(infoPtr->Self, NULL, FALSE);
return 0;
}
static BOOL
STATUSBAR_WMSetText (STATUS_INFO *infoPtr, LPCSTR text)
{
STATUSWINDOWPART *part;
int len;
TRACE("\n");
if (infoPtr->numParts == 0)
return FALSE;
part = &infoPtr->parts[0];
/* duplicate string */
if (part->text)
Free (part->text);
part->text = 0;
if (infoPtr->bUnicode) {
if (text && (len = strlenW((LPCWSTR)text))) {
part->text = Alloc ((len+1)*sizeof(WCHAR));
if (!part->text) return FALSE;
strcpyW (part->text, (LPCWSTR)text);
}
}
else {
if (text && (len = lstrlenA(text))) {
DWORD lenW = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
part->text = Alloc (lenW*sizeof(WCHAR));
if (!part->text) return FALSE;
MultiByteToWideChar( CP_ACP, 0, text, -1, part->text, lenW );
}
}
InvalidateRect(infoPtr->Self, &part->bound, FALSE);
return TRUE;
}
static BOOL
STATUSBAR_WMSize (STATUS_INFO *infoPtr, WORD flags)
{
INT width, x, y;
RECT parent_rect;
/* Need to resize width to match parent */
TRACE("flags %04x\n", flags);
if (flags != SIZE_RESTORED && flags != SIZE_MAXIMIZED) {
WARN("flags MUST be SIZE_RESTORED or SIZE_MAXIMIZED\n");
return FALSE;
}
if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) return FALSE;
/* width and height don't apply */
GetClientRect (infoPtr->Notify, &parent_rect);
width = parent_rect.right - parent_rect.left;
x = parent_rect.left;
y = parent_rect.bottom - infoPtr->height;
MoveWindow (infoPtr->Self, parent_rect.left,
parent_rect.bottom - infoPtr->height,
width, infoPtr->height, TRUE);
STATUSBAR_SetPartBounds (infoPtr);
return TRUE;
}
/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (STATUS_INFO* infoPtr)
{
HTHEME theme = GetWindowTheme (infoPtr->Self);
CloseThemeData (theme);
OpenThemeData (infoPtr->Self, themeClass);
return 0;
}
static LRESULT
STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd)
{
if (cmd == NF_REQUERY) {
INT i = SendMessageW(from, WM_NOTIFYFORMAT, (WPARAM)infoPtr->Self, NF_QUERY);
infoPtr->NtfUnicode = (i == NFR_UNICODE);
}
return infoPtr->NtfUnicode ? NFR_UNICODE : NFR_ANSI;
}
static LRESULT
STATUSBAR_SendNotify (STATUS_INFO *infoPtr, UINT code)
{
NMHDR nmhdr;
TRACE("code %04x\n", code);
nmhdr.hwndFrom = infoPtr->Self;
nmhdr.idFrom = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
nmhdr.code = code;
SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr);
return 0;
}
static LRESULT WINAPI
StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
STATUS_INFO *infoPtr = (STATUS_INFO *)GetWindowLongPtrW (hwnd, 0);
INT nPart = ((INT) wParam) & 0x00ff;
LRESULT res;
TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
if (!infoPtr && msg != WM_CREATE)
return DefWindowProcW (hwnd, msg, wParam, lParam);
switch (msg) {
case SB_GETBORDERS:
return STATUSBAR_GetBorders (infoPtr, (INT *)lParam);
case SB_GETICON:
return (LRESULT)STATUSBAR_GetIcon (infoPtr, nPart);
case SB_GETPARTS:
return STATUSBAR_GetParts (infoPtr, (INT)wParam, (INT *)lParam);
case SB_GETRECT:
return STATUSBAR_GetRect (infoPtr, nPart, (LPRECT)lParam);
case SB_GETTEXTA:
return STATUSBAR_GetTextA (infoPtr, nPart, (LPSTR)lParam);
case SB_GETTEXTW:
return STATUSBAR_GetTextW (infoPtr, nPart, (LPWSTR)lParam);
case SB_GETTEXTLENGTHA:
case SB_GETTEXTLENGTHW:
return STATUSBAR_GetTextLength (infoPtr, nPart);
case SB_GETTIPTEXTA:
return STATUSBAR_GetTipTextA (infoPtr, LOWORD(wParam), (LPSTR)lParam, HIWORD(wParam));
case SB_GETTIPTEXTW:
return STATUSBAR_GetTipTextW (infoPtr, LOWORD(wParam), (LPWSTR)lParam, HIWORD(wParam));
case SB_GETUNICODEFORMAT:
return infoPtr->bUnicode;
case SB_ISSIMPLE:
return infoPtr->simple;
case SB_SETBORDERS:
return STATUSBAR_SetBorders (infoPtr, (INT *)lParam);
case SB_SETBKCOLOR:
return STATUSBAR_SetBkColor (infoPtr, (COLORREF)lParam);
case SB_SETICON:
return STATUSBAR_SetIcon (infoPtr, nPart, (HICON)lParam);
case SB_SETMINHEIGHT:
return STATUSBAR_SetMinHeight (infoPtr, (INT)wParam);
case SB_SETPARTS:
return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam);
case SB_SETTEXTA:
return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, FALSE);
case SB_SETTEXTW:
return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, TRUE);
case SB_SETTIPTEXTA:
return STATUSBAR_SetTipTextA (infoPtr, (INT)wParam, (LPSTR)lParam);
case SB_SETTIPTEXTW:
return STATUSBAR_SetTipTextW (infoPtr, (INT)wParam, (LPWSTR)lParam);
case SB_SETUNICODEFORMAT:
return STATUSBAR_SetUnicodeFormat (infoPtr, (BOOL)wParam);
case SB_SIMPLE:
return STATUSBAR_Simple (infoPtr, (BOOL)wParam);
case WM_CREATE:
return STATUSBAR_WMCreate (hwnd, (LPCREATESTRUCTA)lParam);
case WM_DESTROY:
return STATUSBAR_WMDestroy (infoPtr);
case WM_GETFONT:
return (LRESULT)(infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont);
case WM_GETTEXT:
return STATUSBAR_WMGetText (infoPtr, (INT)wParam, (LPWSTR)lParam);
case WM_GETTEXTLENGTH:
return STATUSBAR_GetTextLength (infoPtr, 0);
case WM_LBUTTONDBLCLK:
return STATUSBAR_SendNotify (infoPtr, NM_DBLCLK);
case WM_LBUTTONUP:
return STATUSBAR_SendNotify (infoPtr, NM_CLICK);
case WM_MOUSEMOVE:
return STATUSBAR_Relay2Tip (infoPtr, msg, wParam, lParam);
case WM_NCHITTEST:
res = STATUSBAR_WMNCHitTest(infoPtr, (short)LOWORD(lParam),
(short)HIWORD(lParam));
if (res != HTERROR) return res;
return DefWindowProcW (hwnd, msg, wParam, lParam);
case WM_NCLBUTTONUP:
case WM_NCLBUTTONDOWN:
PostMessageW (infoPtr->Notify, msg, wParam, lParam);
return 0;
case WM_NOTIFYFORMAT:
return STATUSBAR_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);
case WM_PRINTCLIENT:
case WM_PAINT:
return STATUSBAR_WMPaint (infoPtr, (HDC)wParam);
case WM_RBUTTONDBLCLK:
return STATUSBAR_SendNotify (infoPtr, NM_RDBLCLK);
case WM_RBUTTONUP:
return STATUSBAR_SendNotify (infoPtr, NM_RCLICK);
case WM_SETFONT:
return STATUSBAR_WMSetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
case WM_SETTEXT:
return STATUSBAR_WMSetText (infoPtr, (LPCSTR)lParam);
case WM_SIZE:
if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0;
return DefWindowProcW (hwnd, msg, wParam, lParam);
case WM_THEMECHANGED:
return theme_changed (infoPtr);
default:
if ((msg >= WM_USER) && (msg < WM_APP))
ERR("unknown msg %04x wp=%04x lp=%08lx\n",
msg, wParam, lParam);
return DefWindowProcW (hwnd, msg, wParam, lParam);
}
}
/***********************************************************************
* STATUS_Register [Internal]
*
* Registers the status window class.
*/
void
STATUS_Register (void)
{
WNDCLASSW wndClass;
ZeroMemory (&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
wndClass.lpfnWndProc = StatusWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(STATUS_INFO *);
wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = STATUSCLASSNAMEW;
RegisterClassW (&wndClass);
}
/***********************************************************************
* STATUS_Unregister [Internal]
*
* Unregisters the status window class.
*/
void
STATUS_Unregister (void)
{
UnregisterClassW (STATUSCLASSNAMEW, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -