From 6a944b556ae9ca0609975ee387a57f000cb862e4 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 2 Dec 2018 18:51:44 +0900 Subject: [PATCH] [USER32] Add Ghost window class (#1082) CORE-11944 --- win32ss/user/user32/CMakeLists.txt | 1 + win32ss/user/user32/controls/ghost.c | 620 ++++++++++++++++++++++ win32ss/user/user32/controls/regcontrol.c | 7 +- win32ss/user/user32/include/controls.h | 3 + win32ss/user/user32/include/regcontrol.h | 1 + win32ss/user/user32/include/resource.h | 4 + win32ss/user/user32/lang/bg-BG.rc | 3 + win32ss/user/user32/lang/cs-CZ.rc | 3 + win32ss/user/user32/lang/da-DK.rc | 3 + win32ss/user/user32/lang/de-DE.rc | 3 + win32ss/user/user32/lang/el-GR.rc | 3 + win32ss/user/user32/lang/en-US.rc | 3 + win32ss/user/user32/lang/es-ES.rc | 3 + win32ss/user/user32/lang/fr-FR.rc | 3 + win32ss/user/user32/lang/he-IL.rc | 3 + win32ss/user/user32/lang/hu-HU.rc | 3 + win32ss/user/user32/lang/id-ID.rc | 3 + win32ss/user/user32/lang/it-IT.rc | 3 + win32ss/user/user32/lang/ja-JP.rc | 3 + win32ss/user/user32/lang/lt-LT.rc | 3 + win32ss/user/user32/lang/nl-NL.rc | 3 + win32ss/user/user32/lang/no-NO.rc | 3 + win32ss/user/user32/lang/pl-PL.rc | 3 + win32ss/user/user32/lang/pt-BR.rc | 3 + win32ss/user/user32/lang/ro-RO.rc | 3 + win32ss/user/user32/lang/ru-RU.rc | 3 + win32ss/user/user32/lang/sk-SK.rc | 3 + win32ss/user/user32/lang/sv-SE.rc | 3 + win32ss/user/user32/lang/tr-TR.rc | 3 + win32ss/user/user32/lang/uk-UA.rc | 3 + win32ss/user/user32/lang/zh-CN.rc | 3 + 31 files changed, 708 insertions(+), 3 deletions(-) create mode 100644 win32ss/user/user32/controls/ghost.c diff --git a/win32ss/user/user32/CMakeLists.txt b/win32ss/user/user32/CMakeLists.txt index fdc280a1a09..b048231fb01 100644 --- a/win32ss/user/user32/CMakeLists.txt +++ b/win32ss/user/user32/CMakeLists.txt @@ -11,6 +11,7 @@ list(APPEND SOURCE controls/button.c controls/combo.c controls/edit.c + controls/ghost.c controls/icontitle.c controls/listbox.c controls/regcontrol.c diff --git a/win32ss/user/user32/controls/ghost.c b/win32ss/user/user32/controls/ghost.c new file mode 100644 index 00000000000..ccc9a6c5280 --- /dev/null +++ b/win32ss/user/user32/controls/ghost.c @@ -0,0 +1,620 @@ +/* + * PROJECT: ReactOS user32.dll + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Ghost window class + * COPYRIGHT: Copyright 2018 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(ghost); + +#define GHOST_TIMER_ID 0xFACEDEAD +#define GHOST_INTERVAL 1000 // one second +#define GHOST_PROP L"GhostProp" + +const struct builtin_class_descr GHOST_builtin_class = +{ + L"Ghost", /* name */ + 0, /* style */ + GhostWndProcA, /* procA */ + GhostWndProcW, /* procW */ + 0, /* extra */ + IDC_WAIT, /* cursor */ + NULL /* brush */ +}; + +static HBITMAP +IntCreate32BppBitmap(INT cx, INT cy) +{ + HBITMAP hbm = NULL; + BITMAPINFO bi; + HDC hdc; + LPVOID pvBits; + + ZeroMemory(&bi, sizeof(bi)); + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = cx; + bi.bmiHeader.biHeight = cy; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + + hdc = CreateCompatibleDC(NULL); + if (hdc) + { + hbm = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0); + DeleteDC(hdc); + } + return hbm; +} + +static HBITMAP +IntGetWindowBitmap(HWND hwnd, INT cx, INT cy) +{ + HBITMAP hbm = NULL; + HDC hdc, hdcMem; + HGDIOBJ hbmOld; + + hdc = GetWindowDC(hwnd); + if (!hdc) + return NULL; + + hdcMem = CreateCompatibleDC(hdc); + if (!hdcMem) + goto earth; + + hbm = IntCreate32BppBitmap(cx, cy); + if (hbm) + { + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY | CAPTUREBLT); + SelectObject(hdcMem, hbmOld); + } + + DeleteDC(hdcMem); + +earth: + ReleaseDC(hwnd, hdc); + + return hbm; +} + +static VOID +IntMakeGhostImage(HBITMAP hbm) +{ + BITMAP bm; + DWORD i, *pdw; + + GetObject(hbm, sizeof(bm), &bm); + + if (bm.bmBitsPixel != 32 || !bm.bmBits) + { + ERR("bm.bmBitsPixel == %d, bm.bmBits == %p\n", + bm.bmBitsPixel, bm.bmBits); + return; + } + + pdw = bm.bmBits; + for (i = 0; i < bm.bmWidth * bm.bmHeight; ++i) + { + *pdw = *pdw | 0x00C0C0C0; // bitwise-OR with ARGB #C0C0C0 + ++pdw; + } +} + +/****************************************************************************/ + +typedef struct GHOST_DATA +{ + HWND hwndTarget; + HBITMAP hbm32bpp; + BOOL bDestroyTarget; +} GHOST_DATA; + +static GHOST_DATA * +Ghost_GetData(HWND hwnd) +{ + return (GHOST_DATA *)GetWindowLongPtrW(hwnd, GWLP_USERDATA); +} + +static HWND +Ghost_GetTarget(HWND hwnd) +{ + GHOST_DATA *pData = Ghost_GetData(hwnd); + if (!pData) + return NULL; + return pData->hwndTarget; +} + +static LPWSTR +Ghost_GetText(HWND hwndTarget, INT *pcchTextW, INT cchExtra) +{ + LPWSTR pszTextW = NULL, pszTextNewW; + INT cchNonExtra, cchTextW = *pcchTextW; + + pszTextNewW = HeapAlloc(GetProcessHeap(), 0, cchTextW * sizeof(WCHAR)); + for (;;) + { + if (!pszTextNewW) + { + ERR("HeapAlloc failed\n"); + if (pszTextW) + HeapFree(GetProcessHeap(), 0, pszTextW); + return NULL; + } + pszTextW = pszTextNewW; + + cchNonExtra = cchTextW - cchExtra; + if (InternalGetWindowText(hwndTarget, pszTextW, + cchNonExtra) < cchNonExtra - 1) + { + break; + } + + cchTextW *= 2; + pszTextNewW = HeapReAlloc(GetProcessHeap(), 0, pszTextW, + cchTextW * sizeof(WCHAR)); + } + + *pcchTextW = cchTextW; + return pszTextW; +} + +static BOOL +Ghost_OnCreate(HWND hwnd, CREATESTRUCTW *lpcs) +{ + HBITMAP hbm32bpp; + HWND hwndTarget, hwndPrev; + GHOST_DATA *pData; + RECT rc; + DWORD style, exstyle; + WCHAR szTextW[320], szNotRespondingW[32]; + LPWSTR pszTextW; + INT cchTextW, cchExtraW, cchNonExtraW; + PWND pWnd = ValidateHwnd(hwnd); + if (pWnd) + { + if (!pWnd->fnid) + { + NtUserSetWindowFNID(hwnd, FNID_GHOST); + } + else if (pWnd->fnid != FNID_GHOST) + { + ERR("Wrong window class for Ghost! fnId 0x%x\n", pWnd->fnid); + return FALSE; + } + } + + // get the target + hwndTarget = (HWND)lpcs->lpCreateParams; + if (!IsWindowVisible(hwndTarget) || // invisible? + GetParent(hwndTarget) || // child? + !IsHungAppWindow(hwndTarget)) // not hung? + { + return FALSE; + } + + // check prop + if (GetPropW(hwndTarget, GHOST_PROP)) + return FALSE; + + // set prop + SetPropW(hwndTarget, GHOST_PROP, hwnd); + + // create user data + pData = HeapAlloc(GetProcessHeap(), 0, sizeof(GHOST_DATA)); + if (!pData) + { + ERR("HeapAlloc failed\n"); + return FALSE; + } + + // get window image + GetWindowRect(hwndTarget, &rc); + hbm32bpp = IntGetWindowBitmap(hwndTarget, + rc.right - rc.left, + rc.bottom - rc.top); + if (!hbm32bpp) + { + ERR("hbm32bpp was NULL\n"); + HeapFree(GetProcessHeap(), 0, pData); + return FALSE; + } + // make a ghost image + IntMakeGhostImage(hbm32bpp); + + // set user data + pData->hwndTarget = hwndTarget; + pData->hbm32bpp = hbm32bpp; + pData->bDestroyTarget = FALSE; + SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)pData); + + // get style + style = GetWindowLongPtrW(hwndTarget, GWL_STYLE); + exstyle = GetWindowLongPtrW(hwndTarget, GWL_EXSTYLE); + + // get text + cchTextW = ARRAYSIZE(szTextW); + cchExtraW = ARRAYSIZE(szNotRespondingW); + cchNonExtraW = cchTextW - cchExtraW; + if (InternalGetWindowText(hwndTarget, szTextW, + cchNonExtraW) < cchNonExtraW - 1) + { + pszTextW = szTextW; + } + else + { + cchTextW *= 2; + pszTextW = Ghost_GetText(hwndTarget, &cchTextW, cchExtraW); + if (!pszTextW) + { + ERR("Ghost_GetText failed\n"); + DeleteObject(hbm32bpp); + HeapFree(GetProcessHeap(), 0, pData); + return FALSE; + } + } + + // don't use scrollbars. + style &= ~(WS_HSCROLL | WS_VSCROLL | WS_VISIBLE); + + // set style + SetWindowLongPtrW(hwnd, GWL_STYLE, style); + SetWindowLongPtrW(hwnd, GWL_EXSTYLE, exstyle); + + // set text with " (Not Responding)" + LoadStringW(User32Instance, IDS_NOT_RESPONDING, + szNotRespondingW, ARRAYSIZE(szNotRespondingW)); + StringCchCatW(pszTextW, cchTextW, szNotRespondingW); + SetWindowTextW(hwnd, pszTextW); + + // free the text buffer + if (szTextW != pszTextW) + HeapFree(GetProcessHeap(), 0, pszTextW); + + // get previous window of target + hwndPrev = GetWindow(hwndTarget, GW_HWNDPREV); + + // hide target + ShowWindowAsync(hwndTarget, SW_HIDE); + + // shrink the ghost to zero size and insert. + // this will avoid effects. + SetWindowPos(hwnd, hwndPrev, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | + SWP_DRAWFRAME); + + // resume the position and size of ghost + MoveWindow(hwnd, rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, TRUE); + + // make ghost visible + SetWindowLongPtrW(hwnd, GWL_STYLE, style | WS_VISIBLE); + + // redraw + InvalidateRect(hwnd, NULL, TRUE); + + // start timer + SetTimer(hwnd, GHOST_TIMER_ID, GHOST_INTERVAL, NULL); + + return TRUE; +} + +static void +Ghost_Unenchant(HWND hwnd, BOOL bDestroyTarget) +{ + GHOST_DATA *pData = Ghost_GetData(hwnd); + if (!pData) + return; + + pData->bDestroyTarget |= bDestroyTarget; + DestroyWindow(hwnd); +} + +static void +Ghost_OnDraw(HWND hwnd, HDC hdc) +{ + BITMAP bm; + HDC hdcMem; + GHOST_DATA *pData = Ghost_GetData(hwnd); + + if (!pData || !GetObject(pData->hbm32bpp, sizeof(bm), &bm)) + return; + + hdcMem = CreateCompatibleDC(hdc); + if (hdcMem) + { + HGDIOBJ hbmOld = SelectObject(hdcMem, pData->hbm32bpp); + BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, + hdcMem, 0, 0, SRCCOPY | CAPTUREBLT); + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + } +} + +static void +Ghost_OnNCPaint(HWND hwnd, HRGN hrgn, BOOL bUnicode) +{ + HDC hdc; + + // do the default behaivour + if (bUnicode) + DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)hrgn, 0); + else + DefWindowProcA(hwnd, WM_NCPAINT, (WPARAM)hrgn, 0); + + // draw the ghost image + hdc = GetWindowDC(hwnd); + if (hdc) + { + Ghost_OnDraw(hwnd, hdc); + ReleaseDC(hwnd, hdc); + } +} + +static void +Ghost_OnPaint(HWND hwnd) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + if (hdc) + { + // don't draw at here + EndPaint(hwnd, &ps); + } +} + +static void +Ghost_OnMove(HWND hwnd, int x, int y) +{ + RECT rc; + HWND hwndTarget = Ghost_GetTarget(hwnd); + + GetWindowRect(hwnd, &rc); + + // move the target + SetWindowPos(hwndTarget, NULL, rc.left, rc.top, 0, 0, + SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | + SWP_NOSENDCHANGING); +} + +static void +Ghost_OnDestroy(HWND hwnd) +{ + KillTimer(hwnd, GHOST_TIMER_ID); +} + +static void +Ghost_DestroyTarget(GHOST_DATA *pData) +{ + HWND hwndTarget = pData->hwndTarget; + DWORD pid; + HANDLE hProcess; + + pData->hwndTarget = NULL; + GetWindowThreadProcessId(hwndTarget, &pid); + + hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid); + if (hProcess) + { + TerminateProcess(hProcess, -1); + CloseHandle(hProcess); + } + + DestroyWindow(hwndTarget); +} + +static void +Ghost_OnNCDestroy(HWND hwnd) +{ + // delete the user data + GHOST_DATA *pData = Ghost_GetData(hwnd); + if (pData) + { + SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0); + + // delete image + DeleteObject(pData->hbm32bpp); + pData->hbm32bpp = NULL; + + // remove prop + RemovePropW(pData->hwndTarget, GHOST_PROP); + + // show target + ShowWindowAsync(pData->hwndTarget, SW_SHOWNOACTIVATE); + + // destroy target if necessary + if (pData->bDestroyTarget) + { + Ghost_DestroyTarget(pData); + } + + HeapFree(GetProcessHeap(), 0, pData); + } + + NtUserSetWindowFNID(hwnd, FNID_DESTROY); + + PostQuitMessage(0); +} + +static void +Ghost_OnClose(HWND hwnd) +{ + INT id; + WCHAR szAskTerminate[128]; + WCHAR szHungUpTitle[128]; + + // stop timer + KillTimer(hwnd, GHOST_TIMER_ID); + + LoadStringW(User32Instance, IDS_ASK_TERMINATE, + szAskTerminate, ARRAYSIZE(szAskTerminate)); + LoadStringW(User32Instance, IDS_HUNG_UP_TITLE, + szHungUpTitle, ARRAYSIZE(szHungUpTitle)); + + id = MessageBoxW(hwnd, szAskTerminate, szHungUpTitle, + MB_ICONINFORMATION | MB_YESNO); + if (id == IDYES) + { + // destroy the target + Ghost_Unenchant(hwnd, TRUE); + return; + } + + // restart timer + SetTimer(hwnd, GHOST_TIMER_ID, GHOST_INTERVAL, NULL); +} + +static void +Ghost_OnTimer(HWND hwnd, UINT id) +{ + HWND hwndTarget; + GHOST_DATA *pData = Ghost_GetData(hwnd); + + if (id != GHOST_TIMER_ID || !pData) + return; + + // stop the timer + KillTimer(hwnd, id); + + hwndTarget = pData->hwndTarget; + if (!IsWindow(hwndTarget) || !IsHungAppWindow(hwndTarget)) + { + // resume if window is destroyed or responding + Ghost_Unenchant(hwnd, FALSE); + return; + } + + // restart the timer + SetTimer(hwnd, GHOST_TIMER_ID, GHOST_INTERVAL, NULL); +} + +static HICON +Ghost_GetIcon(HWND hwnd, INT fType) +{ + GHOST_DATA *pData = Ghost_GetData(hwnd); + HICON hIcon = NULL; + + if (!pData) + return NULL; + + // same as the original icon + switch (fType) + { + case ICON_BIG: + { + hIcon = (HICON)GetClassLongPtrW(pData->hwndTarget, GCLP_HICON); + break; + } + + case ICON_SMALL: + { + hIcon = (HICON)GetClassLongPtrW(pData->hwndTarget, GCLP_HICONSM); + break; + } + } + + return hIcon; +} + +LRESULT WINAPI +GhostWndProc_common(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, + BOOL unicode) +{ + switch (uMsg) + { + case WM_CREATE: + if (!Ghost_OnCreate(hwnd, (CREATESTRUCTW *)lParam)) + return -1; + break; + + case WM_NCPAINT: + Ghost_OnNCPaint(hwnd, (HRGN)wParam, unicode); + return 0; + + case WM_ERASEBKGND: + Ghost_OnDraw(hwnd, (HDC)wParam); + return TRUE; + + case WM_PAINT: + Ghost_OnPaint(hwnd); + break; + + case WM_MOVE: + Ghost_OnMove(hwnd, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); + break; + + case WM_SIZE: + break; + + case WM_SIZING: + return TRUE; + + case WM_SYSCOMMAND: + switch ((UINT)wParam) + { + case SC_MAXIMIZE: + case SC_SIZE: + // sizing-related + return 0; + } + if (unicode) + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + else + return DefWindowProcA(hwnd, uMsg, wParam, lParam); + + case WM_CLOSE: + Ghost_OnClose(hwnd); + break; + + case WM_TIMER: + Ghost_OnTimer(hwnd, (UINT)wParam); + break; + + case WM_NCMOUSEMOVE: + if (unicode) + DefWindowProcW(hwnd, uMsg, wParam, lParam); + else + DefWindowProcA(hwnd, uMsg, wParam, lParam); + SetCursor(LoadCursor(NULL, IDC_WAIT)); + return 0; + + case WM_GETICON: + return (LRESULT)Ghost_GetIcon(hwnd, (INT)wParam); + + case WM_COMMAND: + if (LOWORD(wParam) == 3333) + Ghost_Unenchant(hwnd, FALSE); + break; + + case WM_DESTROY: + Ghost_OnDestroy(hwnd); + break; + + case WM_NCDESTROY: + Ghost_OnNCDestroy(hwnd); + break; + + default: + { + if (unicode) + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + else + return DefWindowProcA(hwnd, uMsg, wParam, lParam); + } + } + return 0; +} + +LRESULT CALLBACK +GhostWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return GhostWndProc_common(hwnd, uMsg, wParam, lParam, FALSE); +} + +LRESULT CALLBACK +GhostWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return GhostWndProc_common(hwnd, uMsg, wParam, lParam, TRUE); +} diff --git a/win32ss/user/user32/controls/regcontrol.c b/win32ss/user/user32/controls/regcontrol.c index ff9c9c96096..3360841ffc6 100644 --- a/win32ss/user/user32/controls/regcontrol.c +++ b/win32ss/user/user32/controls/regcontrol.c @@ -64,6 +64,7 @@ static const struct { &EDIT_builtin_class, FNID_EDIT, ICLS_EDIT}, /* { &ICONTITLE_builtin_class, FNID_ICONTITLE, ICLS_ICONTITLE}, // moved to win32k */ { &STATIC_builtin_class, FNID_STATIC, ICLS_STATIC}, + { &GHOST_builtin_class, FNID_GHOST, ICLS_GHOST}, }; BOOL WINAPI RegisterSystemControls(VOID) @@ -175,8 +176,8 @@ BOOL WINAPI RegisterClientPFN(VOID) pfnClientW.pfnStaticWndProc = StaticWndProcW; pfnClientA.pfnImeWndProc = ImeWndProcA; pfnClientW.pfnImeWndProc = ImeWndProcW; - pfnClientA.pfnGhostWndProc = DefWindowProcA; - pfnClientW.pfnGhostWndProc = DefWindowProcW; + pfnClientA.pfnGhostWndProc = GhostWndProcA; + pfnClientW.pfnGhostWndProc = GhostWndProcW; pfnClientA.pfnHkINLPCWPSTRUCT = DefWindowProcA; pfnClientW.pfnHkINLPCWPSTRUCT = DefWindowProcW; pfnClientA.pfnHkINLPCWPRETSTRUCT = DefWindowProcA; @@ -199,7 +200,7 @@ BOOL WINAPI RegisterClientPFN(VOID) pfnClientWorker.pfnMDIClientWndProc = MDIClientWndProc_common; pfnClientWorker.pfnStaticWndProc = StaticWndProc_common; pfnClientWorker.pfnImeWndProc = ImeWndProc_common; - pfnClientWorker.pfnGhostWndProc = User32DefWindowProc; + pfnClientWorker.pfnGhostWndProc = GhostWndProc_common; pfnClientWorker.pfnCtfHookProc = User32DefWindowProc; Status = NtUserInitializeClientPfnArrays( &pfnClientA, diff --git a/win32ss/user/user32/include/controls.h b/win32ss/user/user32/include/controls.h index 15ddd867ae7..317e2f97334 100644 --- a/win32ss/user/user32/include/controls.h +++ b/win32ss/user/user32/include/controls.h @@ -104,6 +104,9 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPAR LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode); +LRESULT WINAPI GhostWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +LRESULT WINAPI GhostWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +LRESULT WINAPI GhostWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode); LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam, BOOL unicode); diff --git a/win32ss/user/user32/include/regcontrol.h b/win32ss/user/user32/include/regcontrol.h index 2b5330cd6c1..f1b3b69bf03 100644 --- a/win32ss/user/user32/include/regcontrol.h +++ b/win32ss/user/user32/include/regcontrol.h @@ -38,6 +38,7 @@ extern const struct builtin_class_descr MDICLIENT_builtin_class; extern const struct builtin_class_descr MENU_builtin_class; extern const struct builtin_class_descr SCROLL_builtin_class; extern const struct builtin_class_descr STATIC_builtin_class; +extern const struct builtin_class_descr GHOST_builtin_class; ATOM WINAPI RegisterClassExWOWW(WNDCLASSEXW *,LPDWORD,WORD,DWORD,BOOL); BOOL FASTCALL VersionRegisterClass(PCWSTR,LPCWSTR,HANDLE,HMODULE *); diff --git a/win32ss/user/user32/include/resource.h b/win32ss/user/user32/include/resource.h index 3d0088fec26..9c1b3694f86 100644 --- a/win32ss/user/user32/include/resource.h +++ b/win32ss/user/user32/include/resource.h @@ -8,6 +8,9 @@ #pragma once #define IDS_ERROR (2) +#define IDS_NOT_RESPONDING (3) +#define IDS_ASK_TERMINATE (4) +#define IDS_HUNG_UP_TITLE (5) /* * Button names IDs. @@ -26,3 +29,4 @@ #define IDS_HELP (808) #define IDS_TRYAGAIN (809) #define IDS_CONTINUE (810) + diff --git a/win32ss/user/user32/lang/bg-BG.rc b/win32ss/user/user32/lang/bg-BG.rc index 01413b769d5..b1a4c308b1a 100644 --- a/win32ss/user/user32/lang/bg-BG.rc +++ b/win32ss/user/user32/lang/bg-BG.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Грешка" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "Добре" IDS_CANCEL "Отказ" IDS_ABORT "Прекъсване" diff --git a/win32ss/user/user32/lang/cs-CZ.rc b/win32ss/user/user32/lang/cs-CZ.rc index 6c74db4b848..aeade5a416b 100644 --- a/win32ss/user/user32/lang/cs-CZ.rc +++ b/win32ss/user/user32/lang/cs-CZ.rc @@ -63,6 +63,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Chyba" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Storno" IDS_ABORT "&Přerušit" diff --git a/win32ss/user/user32/lang/da-DK.rc b/win32ss/user/user32/lang/da-DK.rc index aa4948bf8b3..447b4e2f067 100644 --- a/win32ss/user/user32/lang/da-DK.rc +++ b/win32ss/user/user32/lang/da-DK.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Fejl" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Fortryd" IDS_ABORT "&Afbryd" diff --git a/win32ss/user/user32/lang/de-DE.rc b/win32ss/user/user32/lang/de-DE.rc index 4435576d947..38ccbdfe4a2 100644 --- a/win32ss/user/user32/lang/de-DE.rc +++ b/win32ss/user/user32/lang/de-DE.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Fehler" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Abbrechen" IDS_ABORT "&Abbrechen" diff --git a/win32ss/user/user32/lang/el-GR.rc b/win32ss/user/user32/lang/el-GR.rc index 843406588a9..d750968c932 100644 --- a/win32ss/user/user32/lang/el-GR.rc +++ b/win32ss/user/user32/lang/el-GR.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Σφάλμα" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "’κυρο" IDS_ABORT "&Ματαίωση" diff --git a/win32ss/user/user32/lang/en-US.rc b/win32ss/user/user32/lang/en-US.rc index 41e64bf2a6e..24f3bbaee86 100644 --- a/win32ss/user/user32/lang/en-US.rc +++ b/win32ss/user/user32/lang/en-US.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Error" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Cancel" IDS_ABORT "&Abort" diff --git a/win32ss/user/user32/lang/es-ES.rc b/win32ss/user/user32/lang/es-ES.rc index 51b635829c9..1b2e4548ca3 100644 --- a/win32ss/user/user32/lang/es-ES.rc +++ b/win32ss/user/user32/lang/es-ES.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Error" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "Aceptar" IDS_CANCEL "Cancelar" IDS_ABORT "&Abortar" diff --git a/win32ss/user/user32/lang/fr-FR.rc b/win32ss/user/user32/lang/fr-FR.rc index 609617302b4..ee1cfdf4125 100644 --- a/win32ss/user/user32/lang/fr-FR.rc +++ b/win32ss/user/user32/lang/fr-FR.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Erreur" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Annuler" IDS_ABORT "&Abandonner" diff --git a/win32ss/user/user32/lang/he-IL.rc b/win32ss/user/user32/lang/he-IL.rc index 93b49a1b3f8..d09463ddd6a 100644 --- a/win32ss/user/user32/lang/he-IL.rc +++ b/win32ss/user/user32/lang/he-IL.rc @@ -59,6 +59,9 @@ END STRINGTABLE BEGIN IDS_ERROR "שגיאה" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "אישור" IDS_CANCEL "ביטול" IDS_ABORT "&בטל" diff --git a/win32ss/user/user32/lang/hu-HU.rc b/win32ss/user/user32/lang/hu-HU.rc index c91da00f16d..64194f4d152 100644 --- a/win32ss/user/user32/lang/hu-HU.rc +++ b/win32ss/user/user32/lang/hu-HU.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Hiba" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Mégse" IDS_ABORT "&Megszakít" diff --git a/win32ss/user/user32/lang/id-ID.rc b/win32ss/user/user32/lang/id-ID.rc index 31f9b4c6340..b3e26d9a539 100644 --- a/win32ss/user/user32/lang/id-ID.rc +++ b/win32ss/user/user32/lang/id-ID.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Salah" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Batal" IDS_ABORT "&Batal" diff --git a/win32ss/user/user32/lang/it-IT.rc b/win32ss/user/user32/lang/it-IT.rc index 40dd1b948c3..14a5c8d5f82 100644 --- a/win32ss/user/user32/lang/it-IT.rc +++ b/win32ss/user/user32/lang/it-IT.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Errore" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Annulla" IDS_ABORT "&Interrompi" diff --git a/win32ss/user/user32/lang/ja-JP.rc b/win32ss/user/user32/lang/ja-JP.rc index a9451dc5309..cf5e221c84f 100644 --- a/win32ss/user/user32/lang/ja-JP.rc +++ b/win32ss/user/user32/lang/ja-JP.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "エラー" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "キャンセル" IDS_ABORT "中止(&A)" diff --git a/win32ss/user/user32/lang/lt-LT.rc b/win32ss/user/user32/lang/lt-LT.rc index 4bc6a221f35..30cdd312110 100644 --- a/win32ss/user/user32/lang/lt-LT.rc +++ b/win32ss/user/user32/lang/lt-LT.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Klaida" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "Gerai" IDS_CANCEL "Atsisakyti" IDS_ABORT "N&utraukti" diff --git a/win32ss/user/user32/lang/nl-NL.rc b/win32ss/user/user32/lang/nl-NL.rc index 6ca628e2f9d..28635a19c49 100644 --- a/win32ss/user/user32/lang/nl-NL.rc +++ b/win32ss/user/user32/lang/nl-NL.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Fout" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Annuleren" IDS_ABORT "&Afbreken" diff --git a/win32ss/user/user32/lang/no-NO.rc b/win32ss/user/user32/lang/no-NO.rc index 7ba5d894824..5f2ef946ff5 100644 --- a/win32ss/user/user32/lang/no-NO.rc +++ b/win32ss/user/user32/lang/no-NO.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Feil" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Avbryt" IDS_ABORT "&Avbryt" diff --git a/win32ss/user/user32/lang/pl-PL.rc b/win32ss/user/user32/lang/pl-PL.rc index 9754bca5931..749216c8aaa 100644 --- a/win32ss/user/user32/lang/pl-PL.rc +++ b/win32ss/user/user32/lang/pl-PL.rc @@ -63,6 +63,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Błąd" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Anuluj" IDS_ABORT "&Przerwij" diff --git a/win32ss/user/user32/lang/pt-BR.rc b/win32ss/user/user32/lang/pt-BR.rc index 1917efb4dbf..e28731e47a9 100644 --- a/win32ss/user/user32/lang/pt-BR.rc +++ b/win32ss/user/user32/lang/pt-BR.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Erro" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Cancelar" IDS_ABORT "&Abortar" diff --git a/win32ss/user/user32/lang/ro-RO.rc b/win32ss/user/user32/lang/ro-RO.rc index 8a80fde59ef..039dfdcf186 100644 --- a/win32ss/user/user32/lang/ro-RO.rc +++ b/win32ss/user/user32/lang/ro-RO.rc @@ -63,6 +63,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Eroare" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "Con&firmă" IDS_CANCEL "A&nulează" IDS_ABORT "Aba&ndon" diff --git a/win32ss/user/user32/lang/ru-RU.rc b/win32ss/user/user32/lang/ru-RU.rc index 3f1542667f7..517c503c3f1 100644 --- a/win32ss/user/user32/lang/ru-RU.rc +++ b/win32ss/user/user32/lang/ru-RU.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Ошибка" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Отмена" IDS_ABORT "Пр&ервать" diff --git a/win32ss/user/user32/lang/sk-SK.rc b/win32ss/user/user32/lang/sk-SK.rc index cd02052dba9..c749e4e770d 100644 --- a/win32ss/user/user32/lang/sk-SK.rc +++ b/win32ss/user/user32/lang/sk-SK.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Chyba" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Zrušiť" IDS_ABORT "&Prerušiť" diff --git a/win32ss/user/user32/lang/sv-SE.rc b/win32ss/user/user32/lang/sv-SE.rc index 841e2a02ca9..04c7f44f079 100644 --- a/win32ss/user/user32/lang/sv-SE.rc +++ b/win32ss/user/user32/lang/sv-SE.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Fel" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Avbryt" IDS_ABORT "&Avbryt" diff --git a/win32ss/user/user32/lang/tr-TR.rc b/win32ss/user/user32/lang/tr-TR.rc index 2d081a04564..f318ffaf0d4 100644 --- a/win32ss/user/user32/lang/tr-TR.rc +++ b/win32ss/user/user32/lang/tr-TR.rc @@ -60,6 +60,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Yanlışlık" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "Tamam" IDS_CANCEL "İptal" IDS_ABORT "&Durdur" diff --git a/win32ss/user/user32/lang/uk-UA.rc b/win32ss/user/user32/lang/uk-UA.rc index 42caa463a6a..9c79df5c50a 100644 --- a/win32ss/user/user32/lang/uk-UA.rc +++ b/win32ss/user/user32/lang/uk-UA.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "Помилка" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "OK" IDS_CANCEL "Скасувати" IDS_ABORT "П&ерервати" diff --git a/win32ss/user/user32/lang/zh-CN.rc b/win32ss/user/user32/lang/zh-CN.rc index 8ea07039844..2992309b3e6 100644 --- a/win32ss/user/user32/lang/zh-CN.rc +++ b/win32ss/user/user32/lang/zh-CN.rc @@ -58,6 +58,9 @@ END STRINGTABLE BEGIN IDS_ERROR "错误" + IDS_NOT_RESPONDING " (Not Responding)" + IDS_ASK_TERMINATE "This application is hung up. May I terminate this app?" + IDS_HUNG_UP_TITLE "Hung up!" IDS_OK "确定" IDS_CANCEL "取消" IDS_ABORT "中止(&A)"