Merge branch 'user32_msgbox' into 'master'

user32/msgbox: Support WM_COPY Message

See merge request wine/wine!5247
This commit is contained in:
Alistair Leslie-Hughes 2024-11-18 05:51:28 +00:00
commit c9d3eea192

View file

@ -41,6 +41,11 @@ struct ThreadWindows
HWND *handles;
};
/* Index the order the buttons need to appear to an ID* constant */
static const int buttonOrder[10] = { IDYES, IDNO, IDOK, IDABORT, IDRETRY,
IDCANCEL, IDIGNORE, IDTRYAGAIN,
IDCONTINUE, IDHELP };
static BOOL CALLBACK MSGBOX_EnumProc(HWND hwnd, LPARAM lParam)
{
struct ThreadWindows *threadWindows = (struct ThreadWindows *)lParam;
@ -74,11 +79,6 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
WCHAR *buffer = NULL;
const WCHAR *ptr;
/* Index the order the buttons need to appear to an ID* constant */
static const int buttonOrder[10] = { IDYES, IDNO, IDOK, IDABORT, IDRETRY,
IDCANCEL, IDIGNORE, IDTRYAGAIN,
IDCONTINUE, IDHELP };
nclm.cbSize = sizeof(nclm);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
@ -320,6 +320,95 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
HeapFree( GetProcessHeap(), 0, buffer );
}
static void MSGBOX_CopyToClipbaord( HWND hwnd )
{
int i;
static const WCHAR line[] = L"---------------------------\r\n";
static const WCHAR carriage[] = L"\r\n";
static const WCHAR spaces[] = L" ";
int lenTitle = GetWindowTextLengthW(hwnd) + 1;
int lenMsg = GetWindowTextLengthW(GetDlgItem(hwnd, MSGBOX_IDTEXT)) + 1;
HGLOBAL hMem;
WCHAR *data;
/*
---------------------------
Dialog Title
---------------------------
Dialog Message
---------------------------
Button(s) Text. OK
---------------------------
*/
int len = ((wcslen(carriage) * 3) + (wcslen(line) * 4) + lenTitle + lenMsg) * sizeof(WCHAR);
WCHAR *text = malloc(len);
if (!text)
return;
lstrcpyW(text, line);
if (!GetWindowTextW(hwnd, text + lstrlenW(text), lenTitle))
{
free(text);
return;
}
lstrcatW(text, carriage);
lstrcatW(text, line);
GetWindowTextW(GetDlgItem(hwnd, MSGBOX_IDTEXT), text + lstrlenW(text), lenMsg);
lstrcatW(text, carriage);
lstrcatW(text, line);
for (i = 0; i < ARRAY_SIZE(buttonOrder); i++)
{
HWND hItem = GetDlgItem(hwnd, buttonOrder[i]);
if (GetWindowLongW(hItem, GWL_STYLE) & WS_VISIBLE)
{
WCHAR buffer[1024] = {0};
int j = 0, k = lstrlenW(text);
GetWindowTextW(hItem, buffer, 1024);
while(buffer[j] != 0)
{
if(buffer[j] != '&')
text[k++] = buffer[j];
j++;
}
text[k] = 0;
lstrcatW(text, spaces);
}
}
lstrcatW(text, carriage);
lstrcatW(text, line);
hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, len);
data = GlobalLock(hMem);
lstrcpyW(data, text);
GlobalUnlock(hMem);
OpenClipboard(hwnd);
NtUserEmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
NtUserCloseClipboard();
free(text);
}
HHOOK msghook_handle;
LRESULT CALLBACK msg_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
MSG *msg = (MSG *)lParam;
if (nCode == MSGF_DIALOGBOX && msg->message == WM_KEYUP)
{
if ( (msg->wParam == 'C' || msg->wParam == 'c') && (NtUserGetKeyState(VK_CONTROL) & 0x8000))
{
MSGBOX_CopyToClipbaord(GetParent(msg->hwnd));
}
}
return NtUserCallNextHookEx(msghook_handle, nCode, wParam, lParam);
}
/**************************************************************************
* MSGBOX_DlgProc
@ -336,9 +425,18 @@ static INT_PTR CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message,
SetWindowContextHelpId(hwnd, mbp->dwContextHelpId);
MSGBOX_OnInit(hwnd, mbp);
SetPropA(hwnd, "WINE_MSGBOX_HELPCALLBACK", mbp->lpfnMsgBoxCallback);
msghook_handle = SetWindowsHookExA(WH_MSGFILTER, msg_hook_proc, NULL, GetCurrentThreadId());
break;
}
case WM_COPY:
MSGBOX_CopyToClipbaord(hwnd);
break;
case WM_DESTROY:
NtUserUnhookWindowsHookEx(msghook_handle);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{