mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1226 lines
33 KiB
1226 lines
33 KiB
/**************************************************************************\
|
|
* Module Name: cltxt.h
|
|
*
|
|
* Neutral Client/Server call related routines involving text.
|
|
*
|
|
* Copyright (c) Microsoft Corp. 1990 All Rights Reserved
|
|
*
|
|
* Created: 04-Dec-90
|
|
*
|
|
* History:
|
|
* 04-Dec-90 created by SMeans
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifdef UNICODE
|
|
#define IS_ANSI FALSE
|
|
#else
|
|
#define IS_ANSI TRUE
|
|
#if IS_ANSI != CW_FLAGS_ANSI
|
|
# error("IS_ANSI != CW_FLAGS_ANSI)
|
|
#endif
|
|
#endif
|
|
|
|
#if IS_ANSI
|
|
|
|
NTSTATUS CaptureAnsiString(
|
|
PUNICODE_STRING UnicodeString,
|
|
LPSTR lpszAnsi)
|
|
{
|
|
ANSI_STRING AnsiString;
|
|
NTSTATUS Status;
|
|
|
|
/*
|
|
* !!! LATER
|
|
* Make this handle large strings
|
|
*/
|
|
RtlInitAnsiString(&AnsiString, lpszAnsi);
|
|
*UnicodeString = NtCurrentTeb()->StaticUnicodeString;
|
|
Status = RtlAnsiStringToUnicodeString( UnicodeString, &AnsiString, FALSE );
|
|
ASSERT(NT_SUCCESS(Status));
|
|
return Status;
|
|
}
|
|
|
|
#define CAPTURESTRING(pstr, psz) CaptureAnsiString((pstr), (psz))
|
|
|
|
#else
|
|
|
|
#define CAPTURESTRING(pstr, psz) RtlInitUnicodeString((pstr), (psz))
|
|
|
|
#endif // IS_ANSI
|
|
/***************************************************************************\
|
|
* CreateWindowEx (API)
|
|
*
|
|
* A complete Thank cannot be generated for CreateWindowEx because its last
|
|
* parameter (lpParam) is polymorphic depending on the window's class. If
|
|
* the window class is "MDIClient" then lpParam points to a CLIENTCREATESTRUCT.
|
|
*
|
|
* History:
|
|
* 04-23-91 DarrinM Created.
|
|
* 04-Feb-92 IanJa Unicode/ANSI neutral
|
|
\***************************************************************************/
|
|
|
|
HWND WINAPI CreateWindowEx(
|
|
DWORD dwExStyle,
|
|
LPCTSTR lpClassName,
|
|
LPCTSTR lpWindowName,
|
|
DWORD dwStyle,
|
|
int X,
|
|
int Y,
|
|
int nWidth,
|
|
int nHeight,
|
|
HWND hWndParent,
|
|
HMENU hMenu,
|
|
HINSTANCE hModule,
|
|
LPVOID lpParam)
|
|
{
|
|
|
|
#if 0
|
|
/*
|
|
* We use some of the undocumented bits in dwExStyle to mark a window
|
|
* with certain attributes. Make sure this bits aren't turned on by
|
|
* the app
|
|
*/
|
|
dwExStyle &= ~(WS_EX_MDICHILD | WS_EX_ANSICREATOR);
|
|
#endif
|
|
|
|
if ((dwExStyle & ~WS_EX_VALID40) && (GETEXPWINVER(hModule) >= VER40) ) {
|
|
RIPMSG0(RIP_ERROR, "Invalid 4.0 ExStyle\n");
|
|
return NULL;
|
|
}
|
|
|
|
return _CreateWindowEx(dwExStyle, lpClassName, lpWindowName,
|
|
dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu,
|
|
hModule, lpParam, IS_ANSI, NULL);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* fnHkINLPCWPSTRUCT
|
|
*
|
|
* This gets thunked through the message thunks, so it has the format
|
|
* of a c/s message thunk call.
|
|
*
|
|
* 05-09-91 ScottLu Created.
|
|
* 04-Feb-92 IanJa Unicode/ANSI neutral
|
|
\***************************************************************************/
|
|
|
|
DWORD TEXT_FN(fnHkINLPCWPSTRUCT)(
|
|
PWND pwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
DWORD xParam)
|
|
{
|
|
CWPSTRUCT cwp;
|
|
|
|
cwp.hwnd = HW(pwnd);
|
|
cwp.message = message;
|
|
cwp.wParam = wParam;
|
|
cwp.lParam = lParam;
|
|
|
|
return TEXT_FN(DispatchHook)(MAKELONG(HC_ACTION, WH_CALLWNDPROC),
|
|
(GetClientInfo()->CI_flags & CI_INTERTHREAD_HOOK) != 0,
|
|
(DWORD)&cwp, (HOOKPROC)xParam);
|
|
}
|
|
|
|
DWORD TEXT_FN(fnHkINLPCWPRETSTRUCT)(
|
|
PWND pwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
DWORD xParam)
|
|
{
|
|
CWPRETSTRUCT cwp;
|
|
PCLIENTINFO pci = GetClientInfo();
|
|
|
|
cwp.hwnd = HW(pwnd);
|
|
cwp.message = message;
|
|
cwp.wParam = wParam;
|
|
cwp.lParam = lParam;
|
|
cwp.lResult = pci->dwHookData;
|
|
|
|
return TEXT_FN(DispatchHook)(MAKELONG(HC_ACTION, WH_CALLWNDPROCRET),
|
|
(GetClientInfo()->CI_flags & CI_INTERTHREAD_HOOK) != 0,
|
|
(DWORD)&cwp, (HOOKPROC)xParam);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* DispatchHook
|
|
*
|
|
* This routine exists simply to remember the hook type in the CTI structure
|
|
* so that later inside of CallNextHookEx we know how to thunk the hook
|
|
* call.
|
|
*
|
|
* 05-09-91 ScottLu Created.
|
|
* 04-Feb-92 IanJa Unicode/ANSI neutral
|
|
\***************************************************************************/
|
|
|
|
DWORD TEXT_FN(DispatchHook)(
|
|
int dw,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
HOOKPROC pfn)
|
|
{
|
|
int dwHookSave;
|
|
DWORD nRet;
|
|
PCLIENTINFO pci;
|
|
#ifdef WX86
|
|
HOOKPROC pfnHook;
|
|
#endif
|
|
|
|
/*
|
|
* First save the current hook stored in the CTI structure in case we're
|
|
* being recursed into. dw contains MAKELONG(nCode, nFilterType).
|
|
*/
|
|
pci = GetClientInfo();
|
|
dwHookSave = pci->dwHookCurrent;
|
|
pci->dwHookCurrent = (dw & 0xFFFF0000) | IS_ANSI;
|
|
|
|
#ifdef WX86
|
|
|
|
//
|
|
// If this is an x86 hook proc, fetch a risc thunk to call
|
|
//
|
|
|
|
pfnHook = (PVOID)((ULONG)pfn & ~0x80000000);
|
|
if (pfn != pfnHook) {
|
|
pfn = pfnWx86HookCallBack(HIWORD(dw), // filter type
|
|
pfnHook // hook proc
|
|
);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
* Call the hook. dw contains MAKELONG(nCode, nFilterType).
|
|
*/
|
|
nRet = pfn(LOWORD(dw), wParam, lParam);
|
|
|
|
/*
|
|
* Restore the hook number and return the return code.
|
|
*/
|
|
pci->dwHookCurrent = dwHookSave;
|
|
return nRet;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* GetWindowLong, SetWindowLong, GetClassLong
|
|
*
|
|
* History:
|
|
* 02-Feb-92 IanJa Neutral version.
|
|
\***************************************************************************/
|
|
|
|
LONG APIENTRY GetWindowLong(HWND hwnd, int nIndex)
|
|
{
|
|
PWND pwnd;
|
|
|
|
pwnd = ValidateHwnd(hwnd);
|
|
|
|
if (pwnd == NULL)
|
|
return 0;
|
|
|
|
return _GetWindowLong(pwnd, nIndex, IS_ANSI);
|
|
}
|
|
|
|
LONG APIENTRY SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong)
|
|
{
|
|
return _SetWindowLong(hWnd, nIndex, dwNewLong, IS_ANSI);
|
|
}
|
|
|
|
DWORD APIENTRY GetClassLong(HWND hWnd, int nIndex)
|
|
{
|
|
PWND pwnd;
|
|
|
|
pwnd = ValidateHwnd(hWnd);
|
|
|
|
if (pwnd == NULL)
|
|
return 0;
|
|
|
|
return _GetClassLong(pwnd, nIndex, IS_ANSI);
|
|
}
|
|
|
|
|
|
BOOL APIENTRY PeekMessage(
|
|
LPMSG lpMsg,
|
|
HWND hWnd,
|
|
UINT wMsgFilterMin,
|
|
UINT wMsgFilterMax,
|
|
UINT wRemoveMsg)
|
|
{
|
|
PCLIENTTHREADINFO pcti;
|
|
PCLIENTINFO pci;
|
|
UINT fsWakeMask;
|
|
UINT cSpinLimit;
|
|
|
|
pci = GetClientInfo();
|
|
|
|
if (hWnd != NULL) {
|
|
goto lbCallServer;
|
|
}
|
|
|
|
#ifdef FE_SB // PeekMessage()
|
|
#if IS_ANSI
|
|
/*
|
|
* If we have a DBCS TrailingByte that should be returned to App,
|
|
* we should pass it, never can fail....
|
|
*/
|
|
if (GetCallBackDbcsInfo()->wParam) {
|
|
/*
|
|
* Check message filter... WM_CHAR should be in the Range...
|
|
*/
|
|
if ((!wMsgFilterMin && !wMsgFilterMax) ||
|
|
(wMsgFilterMin <= WM_CHAR && wMsgFilterMax >=WM_CHAR))
|
|
{
|
|
goto lbCallServer;
|
|
}
|
|
}
|
|
#endif
|
|
#endif // FE_SB
|
|
|
|
if ( (pci->dwTIFlags & TIF_16BIT)
|
|
&& !(wRemoveMsg & PM_NOYIELD)
|
|
&& ((gpsi->nEvents != 0) || (pci->dwTIFlags & TIF_FIRSTIDLE))) {
|
|
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* If we can't see the client thread info, we need to go to the kernel.
|
|
*/
|
|
if ((pcti = pci->pClientThreadInfo) == NULL) {
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* If any appropriate input is available, we need to go to the kernel.
|
|
*/
|
|
if (wMsgFilterMax == 0) {
|
|
fsWakeMask = QS_ALLEVENTS | QS_EVENT | QS_SENDMESSAGE;
|
|
} else {
|
|
fsWakeMask = CalcWakeMask(wMsgFilterMin, wMsgFilterMax) | QS_SENDMESSAGE;
|
|
}
|
|
if ((pcti->fsChangeBits | pcti->fsWakeBits) & fsWakeMask) {
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* If this thread has the queue locked, we have to go to the kernel
|
|
* or other threads on the same queue may be prevented from getting
|
|
* input messages.
|
|
*/
|
|
if (pcti->CTIF_flags & CTIF_SYSQUEUELOCKED) {
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* This is the peek message count (not going idle count). If it gets
|
|
* to be 100 or greater, call the server. This'll cause this app to be
|
|
* put at background priority until it sleeps. This is really important
|
|
* for compatibility because win3.1 peek/getmessage usually takes a trip
|
|
* through the win3.1 scheduler and runs the next task.
|
|
*/
|
|
pci->cSpins++;
|
|
|
|
if ((pci->cSpins >= CSPINBACKGROUND) && !(pci->dwTIFlags & TIF_SPINNING)) {
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* We have to go to the server if someone is waiting on this event.
|
|
* We used to just wait until the spin cound got large but for some
|
|
* apps like terminal. They always just call PeekMessage and after
|
|
* just a few calls they would blink their caret which bonks the spincount
|
|
*/
|
|
if (pci->dwTIFlags & TIF_WAITFORINPUTIDLE){
|
|
goto lbCallServer;
|
|
}
|
|
|
|
/*
|
|
* Make sure we go to the kernel at least once a second so that
|
|
* hung app painting won't occur.
|
|
*/
|
|
if ((NtGetTickCount() - pcti->timeLastRead) > 1000) {
|
|
NtUserGetThreadState(UserThreadStatePeekMessage);
|
|
}
|
|
|
|
/*
|
|
* Determine the maximum number of spins before we yield. Yields
|
|
* are performed more frequently for 16 bit apps.
|
|
*/
|
|
if ((pci->dwTIFlags & TIF_16BIT) && !(wRemoveMsg & PM_NOYIELD)) {
|
|
cSpinLimit = CSPINBACKGROUND / 10;
|
|
} else {
|
|
cSpinLimit = CSPINBACKGROUND;
|
|
}
|
|
|
|
/*
|
|
* If the PeekMessage() is just spinning, then we should sleep
|
|
* just enough so that we allow other processes to gain CPU time.
|
|
* A problem was found when an OLE app tries to communicate to a
|
|
* background app (via SendMessage) running at the same priority as a
|
|
* background/spinning process. This will starve the CPU from those
|
|
* processes. Sleep on every re-cycle of the spin-count. This will
|
|
* assure that apps doing peeks are degraded.
|
|
*
|
|
*/
|
|
if ((pci->dwTIFlags & TIF_SPINNING) && (pci->cSpins >= cSpinLimit)) {
|
|
pci->cSpins = 0;
|
|
NtYieldExecution();
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
lbCallServer:
|
|
|
|
return _PeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax,
|
|
wRemoveMsg, IS_ANSI);
|
|
}
|
|
|
|
LONG APIENTRY DefWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PWND pwnd;
|
|
|
|
if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
|
|
switch (message) {
|
|
case WM_CTLCOLORBTN:
|
|
case WM_CTLCOLORSTATIC:
|
|
case WM_CTLCOLORDLG:
|
|
case WM_CTLCOLORMSGBOX:
|
|
|
|
/*
|
|
* Draw default colors
|
|
*/
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return DefWindowProcWorker(pwnd, message, wParam, lParam, IS_ANSI);
|
|
}
|
|
|
|
LONG APIENTRY SendMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PWND pwnd;
|
|
|
|
/*
|
|
* Prevent apps from setting hi 16 bits so we can use them internally.
|
|
*/
|
|
if (message & RESERVED_MSG_BITS) {
|
|
RIPERR1(ERROR_INVALID_PARAMETER,
|
|
RIP_WARNING,
|
|
"Invalid parameter \"message\" (%ld) to SendMessage",
|
|
message);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Thunk through a special sendmessage for -1 hwnd's so that the general
|
|
* purpose thunks don't allow -1 hwnd's.
|
|
*/
|
|
if (hwnd == (HWND)0xFFFFFFFF || hwnd == (HWND)0x0000FFFF) {
|
|
/*
|
|
* Get a real hwnd so the thunks will validation ok. Note that since
|
|
* -1 hwnd is really rare, calling GetDesktopWindow() here is not a
|
|
* big deal.
|
|
*/
|
|
hwnd = GetDesktopWindow();
|
|
|
|
/*
|
|
* Always send broadcast requests straight to the server.
|
|
* Note: if the xParam needs to be used, must update
|
|
* SendMsgTimeout, FNID_SENDMESSAGEFF uses it to id who
|
|
* it is from...
|
|
*/
|
|
return CsSendMessage(hwnd, message, wParam, lParam, 0L,
|
|
FNID_SENDMESSAGEFF, IS_ANSI);
|
|
}
|
|
|
|
if ((pwnd = ValidateHwnd(hwnd)) == NULL)
|
|
return 0;
|
|
|
|
return SendMessageWorker(pwnd, message, wParam, lParam, IS_ANSI);
|
|
}
|
|
|
|
|
|
LONG APIENTRY SendMessageTimeout(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam,
|
|
UINT fuFlags, UINT uTimeout, LPDWORD lpdwResult)
|
|
|
|
{
|
|
return SendMessageTimeoutWorker(hwnd, message, wParam, lParam,
|
|
fuFlags, uTimeout, lpdwResult, IS_ANSI);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* SendDlgItemMessage
|
|
*
|
|
* Translates the message, calls SendDlgItemMessage on server side. The
|
|
* dialog item's ID is passed as the xParam. On the server side, a stub
|
|
* rearranges the parameters to put the ID where it belongs and calls
|
|
* xxxSendDlgItemMessage.
|
|
*
|
|
* 04-17-91 DarrinM Created.
|
|
\***************************************************************************/
|
|
|
|
LONG WINAPI SendDlgItemMessage(
|
|
HWND hwnd,
|
|
int id,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
if (hwnd == (HWND)0xFFFFFFFF || hwnd == (HWND)0x0000FFFF)
|
|
return 0;
|
|
|
|
if (hwnd = GetDlgItem(hwnd, id))
|
|
return SendMessage(hwnd, message, wParam, lParam);
|
|
|
|
return 0L;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* GetDlgItemText
|
|
*
|
|
* History:
|
|
* 04 Feb 1992 GregoryW Neutral ANSI/Unicode version
|
|
\***************************************************************************/
|
|
|
|
UINT GetDlgItemText(
|
|
HWND hwnd,
|
|
int id,
|
|
LPTSTR lpch,
|
|
int cchMax)
|
|
{
|
|
if ((hwnd = GetDlgItem(hwnd, id)) != NULL) {
|
|
return GetWindowText(hwnd, lpch, cchMax);
|
|
}
|
|
|
|
/*
|
|
* If we couldn't find the window, just null terminate lpch so that the
|
|
* app doesn't gp fault if it tries to run through the text.
|
|
*/
|
|
if (cchMax)
|
|
*lpch = (TCHAR)0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* SetDlgItemText
|
|
*
|
|
* History:
|
|
* 04 Feb 1992 GregoryW Neutral ANSI/Unicode version
|
|
\***************************************************************************/
|
|
|
|
BOOL SetDlgItemText(
|
|
HWND hwnd,
|
|
int id,
|
|
LPCTSTR lpch)
|
|
{
|
|
if ((hwnd = GetDlgItem(hwnd, id)) != NULL) {
|
|
return SetWindowText(hwnd, lpch);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
int WINAPI GetWindowText(
|
|
HWND hwnd,
|
|
LPTSTR lpName,
|
|
int nMaxCount)
|
|
{
|
|
PWND pwnd;
|
|
|
|
/*
|
|
* Don't try to fill a non-existent buffer
|
|
*/
|
|
if (lpName == NULL || nMaxCount == 0) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Initialize string empty, in case SendMessage aborts validation
|
|
*/
|
|
*lpName = TEXT('\0');
|
|
|
|
/*
|
|
* Make sure we have a valid window.
|
|
*/
|
|
if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This process comparison is bogus, but it is what win3.1 does.
|
|
*/
|
|
if (TestWindowProcess(pwnd)) {
|
|
return SendMessageWorker(pwnd, WM_GETTEXT, nMaxCount, (LONG)lpName, IS_ANSI);
|
|
} else {
|
|
return DefWindowProcWorker(pwnd, WM_GETTEXT, nMaxCount, (LONG)lpName, IS_ANSI);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* For MIPS, wrap the GetWindowTextLengthW function to work around a compiler
|
|
* bug that is present in released code (MIPS CTL3D32 around Version 2.29)
|
|
* This is bug #5219 and (large) family. See mips\gtlength.s (puts v0 in v1)
|
|
*/
|
|
#if defined(MIPS) && defined(UNICODE)
|
|
int WINAPI GetWindowTextLengthW2(
|
|
#else
|
|
int WINAPI GetWindowTextLength(
|
|
#endif
|
|
HWND hwnd)
|
|
{
|
|
PWND pwnd;
|
|
|
|
/*
|
|
* Make sure we have a valid window.
|
|
*/
|
|
if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This process comparison is bogus, but it is what win3.1 does.
|
|
*/
|
|
if (TestWindowProcess(pwnd)) {
|
|
return SendMessageWorker(pwnd, WM_GETTEXTLENGTH, 0, 0, IS_ANSI);
|
|
} else {
|
|
return DefWindowProcWorker(pwnd, WM_GETTEXTLENGTH, 0, 0, IS_ANSI);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL WINAPI SetWindowText(
|
|
HWND hwnd,
|
|
LPCTSTR pString)
|
|
{
|
|
int lReturn;
|
|
PWND pwnd;
|
|
|
|
/*
|
|
* Make sure we have a valid window.
|
|
*/
|
|
if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* This process comparison is bogus, but it is what win3.1 does.
|
|
*/
|
|
if (TestWindowProcess(pwnd)) {
|
|
lReturn = SendMessageWorker(pwnd, WM_SETTEXT, 0, (LONG)pString, IS_ANSI);
|
|
} else {
|
|
lReturn = DefWindowProcWorker(pwnd, WM_SETTEXT, 0, (LONG)pString, IS_ANSI);
|
|
}
|
|
return (lReturn >= 0);
|
|
}
|
|
|
|
|
|
LONG APIENTRY DispatchMessage(CONST MSG *lpMsg)
|
|
{
|
|
extern LONG DispatchMessageWorker(CONST MSG *lpMsg, BOOL fAnsi);
|
|
|
|
return DispatchMessageWorker(lpMsg, IS_ANSI);
|
|
}
|
|
|
|
#if IS_ANSI
|
|
void CopyLogFontAtoW(
|
|
PLOGFONTW pdest,
|
|
PLOGFONTA psrc)
|
|
{
|
|
LPSTR lpstrFont = (LPSTR)(&psrc->lfFaceName);
|
|
LPWSTR lpstrFontW = (LPWSTR)(&pdest->lfFaceName);
|
|
|
|
memcpy((LPBYTE)pdest, psrc, sizeof(LOGFONTA) - LF_FACESIZE);
|
|
memset(pdest->lfFaceName, 0, LF_FACESIZE * sizeof(WCHAR));
|
|
MBToWCS(lpstrFont, -1, &lpstrFontW, LF_FACESIZE, FALSE);
|
|
}
|
|
|
|
void CopyLogFontWtoA(
|
|
PLOGFONTA pdest,
|
|
PLOGFONTW psrc)
|
|
{
|
|
LPSTR lpstrFont = (LPSTR)(&pdest->lfFaceName);
|
|
|
|
memcpy((LPBYTE)pdest, (LPBYTE)psrc, sizeof(LOGFONTA) - LF_FACESIZE);
|
|
memset(pdest->lfFaceName, 0, LF_FACESIZE);
|
|
WCSToMB(psrc->lfFaceName, -1, &lpstrFont, LF_FACESIZE, FALSE);
|
|
}
|
|
#endif // IS_ANSI
|
|
|
|
/***************************************************************************\
|
|
* SystemParametersInfo
|
|
*
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL APIENTRY SystemParametersInfo(
|
|
UINT wFlag,
|
|
UINT wParam,
|
|
PVOID lParam,
|
|
UINT flags)
|
|
{
|
|
#if IS_ANSI
|
|
NONCLIENTMETRICSW ClientMetricsW;
|
|
ICONMETRICSW IconMetricsW;
|
|
LOGFONTW LogFontW;
|
|
#endif
|
|
UNICODE_STRING strlParam;
|
|
BOOL fSuccess;
|
|
PVOID oldlParam = lParam;
|
|
|
|
switch (wFlag) {
|
|
case SPI_SCREENSAVERRUNNING:
|
|
return 0;
|
|
|
|
case SPI_SETDESKPATTERN:
|
|
|
|
if (wParam == 0x0000FFFF)
|
|
wParam = (WPARAM)-1;
|
|
|
|
/*
|
|
* lParam not a string (and already copied)
|
|
*/
|
|
if (wParam == (WPARAM)-1)
|
|
break;
|
|
|
|
/*
|
|
* lParam is possibly 0 or -1 (filled in already) or a string
|
|
*/
|
|
if ((lParam != (PVOID)0) && (lParam != (PVOID)-1)) {
|
|
CAPTURESTRING(&strlParam, (LPTSTR)lParam);
|
|
lParam = &strlParam;
|
|
}
|
|
break;
|
|
|
|
case SPI_SETDESKWALLPAPER: {
|
|
|
|
/*
|
|
* lParam is possibly 0, -1 or -2 (filled in already) or a string.
|
|
* Get a pointer to the string so we can use it later. We're
|
|
* going to a bit of normalizing here for consistency.
|
|
*
|
|
* If the caller passes in 0, -1 or -2, we're going to set
|
|
* the wParam to -1, and use the lParam to pass the string
|
|
* representation of the wallpaper.
|
|
*/
|
|
if ((lParam != (PVOID) 0) &&
|
|
(lParam != (PVOID)-1) &&
|
|
(lParam != (PVOID)-2)) {
|
|
|
|
CAPTURESTRING(&strlParam, (LPTSTR)lParam);
|
|
wParam = 0;
|
|
lParam = &strlParam;
|
|
|
|
} else {
|
|
wParam = (WPARAM)-1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETANIMATION:
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ANIMATIONINFO)))
|
|
return FALSE;;
|
|
break;
|
|
|
|
case SPI_GETNONCLIENTMETRICS:
|
|
#if IS_ANSI
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSA)))
|
|
return FALSE;;
|
|
lParam = &ClientMetricsW;
|
|
#else
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSW)))
|
|
return FALSE;;
|
|
#endif
|
|
break;
|
|
|
|
case SPI_GETMINIMIZEDMETRICS:
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(MINIMIZEDMETRICS)))
|
|
return FALSE;;
|
|
break;
|
|
|
|
case SPI_GETICONMETRICS:
|
|
#if IS_ANSI
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ICONMETRICSA)))
|
|
return FALSE;;
|
|
lParam = &IconMetricsW;
|
|
#else
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ICONMETRICSW)))
|
|
return FALSE;;
|
|
#endif
|
|
break;
|
|
|
|
#if IS_ANSI
|
|
case SPI_GETICONTITLELOGFONT:
|
|
lParam = &LogFontW;
|
|
break;
|
|
#endif
|
|
|
|
case SPI_SETANIMATION:
|
|
{
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ANIMATIONINFO)))
|
|
return FALSE;;
|
|
}
|
|
break;
|
|
|
|
case SPI_SETNONCLIENTMETRICS:
|
|
#if IS_ANSI
|
|
{
|
|
PNONCLIENTMETRICSA psrc = (PNONCLIENTMETRICSA)lParam;
|
|
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSA)))
|
|
return FALSE;
|
|
|
|
if( psrc->iCaptionWidth > 256 )
|
|
psrc->iCaptionWidth = 256;
|
|
|
|
if( psrc->iCaptionHeight > 256 )
|
|
psrc->iCaptionHeight = 256;
|
|
|
|
ClientMetricsW.cbSize = psrc->cbSize;
|
|
ClientMetricsW.iBorderWidth = psrc->iBorderWidth;
|
|
ClientMetricsW.iScrollWidth = psrc->iScrollWidth;
|
|
ClientMetricsW.iScrollHeight = psrc->iScrollHeight;
|
|
ClientMetricsW.iCaptionWidth = psrc->iCaptionWidth;
|
|
ClientMetricsW.iCaptionHeight = psrc->iCaptionHeight;
|
|
ClientMetricsW.iSmCaptionWidth = psrc->iSmCaptionWidth;
|
|
ClientMetricsW.iSmCaptionHeight = psrc->iSmCaptionHeight;
|
|
ClientMetricsW.iMenuWidth = psrc->iMenuWidth;
|
|
ClientMetricsW.iMenuHeight = psrc->iMenuHeight;
|
|
|
|
CopyLogFontAtoW(&(ClientMetricsW.lfCaptionFont), &(psrc->lfCaptionFont));
|
|
CopyLogFontAtoW(&(ClientMetricsW.lfSmCaptionFont), &(psrc->lfSmCaptionFont));
|
|
CopyLogFontAtoW(&(ClientMetricsW.lfMenuFont), &(psrc->lfMenuFont));
|
|
CopyLogFontAtoW(&(ClientMetricsW.lfStatusFont), &(psrc->lfStatusFont));
|
|
CopyLogFontAtoW(&(ClientMetricsW.lfMessageFont), &(psrc->lfMessageFont));
|
|
|
|
lParam = &ClientMetricsW;
|
|
}
|
|
#else
|
|
{
|
|
PNONCLIENTMETRICSA psrc;
|
|
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSW)))
|
|
return FALSE;
|
|
|
|
psrc = (PNONCLIENTMETRICSA)lParam;
|
|
|
|
if( psrc->iCaptionWidth > 256 )
|
|
psrc->iCaptionWidth = 256;
|
|
|
|
if( psrc->iCaptionHeight > 256 )
|
|
psrc->iCaptionHeight = 256;
|
|
}
|
|
#endif
|
|
wParam = sizeof(NONCLIENTMETRICSW);
|
|
break;
|
|
|
|
case SPI_SETMINIMIZEDMETRICS:
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(MINIMIZEDMETRICS)))
|
|
return FALSE;;
|
|
wParam = sizeof(MINIMIZEDMETRICS);
|
|
break;
|
|
|
|
case SPI_SETICONMETRICS:
|
|
#if IS_ANSI
|
|
{
|
|
PICONMETRICSA psrc = (PICONMETRICSA)lParam;
|
|
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ICONMETRICSA)))
|
|
return FALSE;;
|
|
|
|
memcpy(&IconMetricsW, psrc, sizeof(ICONMETRICSA) - sizeof(LOGFONTA));
|
|
|
|
CopyLogFontAtoW(&(IconMetricsW.lfFont), &(psrc->lfFont));
|
|
lParam = &IconMetricsW;
|
|
}
|
|
#else
|
|
if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(ICONMETRICSW)))
|
|
return FALSE;;
|
|
#endif
|
|
wParam = sizeof(ICONMETRICSW);
|
|
break;
|
|
|
|
case SPI_SETICONTITLELOGFONT:
|
|
#if IS_ANSI
|
|
CopyLogFontAtoW(&LogFontW, lParam);
|
|
lParam = &LogFontW;
|
|
#endif
|
|
wParam = sizeof(LOGFONTW);
|
|
break;
|
|
|
|
case SPI_GETFILTERKEYS:
|
|
{
|
|
if ((((LPFILTERKEYS)lParam)->cbSize == 0) ||
|
|
(((LPFILTERKEYS)lParam)->cbSize) > sizeof(FILTERKEYS)) {
|
|
return FALSE;;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETSTICKYKEYS:
|
|
{
|
|
if ((((LPSTICKYKEYS)lParam)->cbSize == 0) ||
|
|
(((LPSTICKYKEYS)lParam)->cbSize) > sizeof(STICKYKEYS)) {
|
|
return FALSE;;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETTOGGLEKEYS:
|
|
{
|
|
if ((((LPTOGGLEKEYS)lParam)->cbSize == 0) ||
|
|
(((LPTOGGLEKEYS)lParam)->cbSize) > sizeof(TOGGLEKEYS)) {
|
|
return FALSE;;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETMOUSEKEYS:
|
|
{
|
|
if ((((LPMOUSEKEYS)lParam)->cbSize == 0) ||
|
|
(((LPMOUSEKEYS)lParam)->cbSize) > sizeof(MOUSEKEYS)) {
|
|
return FALSE;;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETACCESSTIMEOUT:
|
|
{
|
|
if ((((LPACCESSTIMEOUT)lParam)->cbSize == 0) ||
|
|
(((LPACCESSTIMEOUT)lParam)->cbSize) > sizeof(ACCESSTIMEOUT)) {
|
|
return FALSE;;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_GETSOUNDSENTRY:
|
|
/*
|
|
* Note: Currently we don't support the windows effect dll
|
|
* option for sound sentry. Therefore, we don't have to
|
|
* deal with the lpszWindowsEffectDLL field (which can be
|
|
* ANSI or Unicode).
|
|
*/
|
|
{
|
|
if ((((LPSOUNDSENTRY)lParam)->cbSize == 0) ||
|
|
(((LPSOUNDSENTRY)lParam)->cbSize) > sizeof(SOUNDSENTRY)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPI_SETUSERPREFERENCE:
|
|
/*
|
|
* Validation goes here: value, range, sign, etc.
|
|
* switch(wParam) case SPI_UP_*
|
|
*/
|
|
|
|
// fall through
|
|
|
|
case SPI_GETUSERPREFERENCE:
|
|
if (wParam >= SPI_UP_COUNT) {
|
|
RIPMSG1(RIP_WARNING, "SystemParametersInfo: Invalid SPI_UP_*: %d", wParam);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
fSuccess = NtUserSystemParametersInfo(wFlag, wParam, lParam, flags, IS_ANSI);
|
|
|
|
#if IS_ANSI
|
|
switch (wFlag) {
|
|
case SPI_GETNONCLIENTMETRICS:
|
|
{
|
|
PNONCLIENTMETRICSA pdst = (PNONCLIENTMETRICSA)oldlParam;
|
|
|
|
pdst->cbSize = sizeof(NONCLIENTMETRICSA);
|
|
pdst->iBorderWidth = ClientMetricsW.iBorderWidth;
|
|
pdst->iScrollWidth = ClientMetricsW.iScrollWidth;
|
|
pdst->iScrollHeight = ClientMetricsW.iScrollHeight;
|
|
pdst->iCaptionWidth = ClientMetricsW.iCaptionWidth;
|
|
pdst->iCaptionHeight = ClientMetricsW.iCaptionHeight;
|
|
pdst->iSmCaptionWidth = ClientMetricsW.iSmCaptionWidth;
|
|
pdst->iSmCaptionHeight = ClientMetricsW.iSmCaptionHeight;
|
|
pdst->iMenuWidth = ClientMetricsW.iMenuWidth;
|
|
pdst->iMenuHeight = ClientMetricsW.iMenuHeight;
|
|
|
|
CopyLogFontWtoA(&(pdst->lfCaptionFont), &(ClientMetricsW.lfCaptionFont));
|
|
CopyLogFontWtoA(&(pdst->lfSmCaptionFont), &(ClientMetricsW.lfSmCaptionFont));
|
|
CopyLogFontWtoA(&(pdst->lfMenuFont), &(ClientMetricsW.lfMenuFont));
|
|
CopyLogFontWtoA(&(pdst->lfStatusFont), &(ClientMetricsW.lfStatusFont));
|
|
CopyLogFontWtoA(&(pdst->lfMessageFont), &(ClientMetricsW.lfMessageFont));
|
|
}
|
|
break;
|
|
|
|
case SPI_GETICONMETRICS:
|
|
{
|
|
PICONMETRICSA pdst = (PICONMETRICSA)oldlParam;
|
|
|
|
memcpy(pdst, &IconMetricsW, sizeof(ICONMETRICSA) - sizeof(LOGFONTA));
|
|
pdst->cbSize = sizeof(ICONMETRICSA);
|
|
|
|
CopyLogFontWtoA(&(pdst->lfFont), &(IconMetricsW.lfFont));
|
|
}
|
|
break;
|
|
|
|
case SPI_GETICONTITLELOGFONT:
|
|
{
|
|
CopyLogFontWtoA((PLOGFONTA)oldlParam, &LogFontW);
|
|
}
|
|
break;
|
|
|
|
}
|
|
#endif // IS_ANSI
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
|
|
HANDLE APIENTRY GetProp(HWND hwnd, LPCTSTR pString) {
|
|
PWND pwnd;
|
|
int iString;
|
|
|
|
if (HIWORD(pString) != 0) {
|
|
iString = (int)GlobalFindAtom(pString);
|
|
if (iString == 0)
|
|
return NULL;
|
|
} else
|
|
iString = (int) pString;
|
|
|
|
pwnd = ValidateHwnd(hwnd);
|
|
|
|
if (pwnd == NULL)
|
|
return NULL;
|
|
|
|
return _GetProp(pwnd, (LPWSTR)iString, FALSE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* RegisterClassW(API)
|
|
*
|
|
* History:
|
|
* 28-Jul-1992 ChandanC Created.
|
|
\***************************************************************************/
|
|
ATOM
|
|
WINAPI
|
|
TEXT_FN(RegisterClass)(
|
|
CONST WNDCLASS *lpWndClass )
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
memcpy(&(wc.style), lpWndClass, sizeof(WNDCLASS));
|
|
wc.hIconSm = NULL;
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
|
|
return TEXT_FN(RegisterClassExWOW)(&wc, NULL, NULL, 0);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* RegisterClassExW(API)
|
|
*
|
|
* History:
|
|
* 28-Jul-1992 ChandanC Created.
|
|
\***************************************************************************/
|
|
ATOM
|
|
WINAPI
|
|
TEXT_FN(RegisterClassEx)(
|
|
CONST WNDCLASSEX *lpWndClass)
|
|
{
|
|
if (lpWndClass->cbSize != sizeof(WNDCLASSEX)) {
|
|
RIPERR1(ERROR_INVALID_PARAMETER,
|
|
RIP_WARNING,
|
|
"RegisterClassEx: cbsize is wrong %lX",
|
|
lpWndClass->cbSize);
|
|
|
|
return 0;
|
|
} else {
|
|
return TEXT_FN(RegisterClassExWOW)((LPWNDCLASSEX)lpWndClass,
|
|
NULL, NULL, 0);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// GetMenuString() -
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
int GetMenuString(HMENU hMenu, UINT wID, LPTSTR lpsz, int cchMax, UINT flags)
|
|
{
|
|
MENUITEMINFO mii;
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
#ifdef MEMPHIS_MENUS
|
|
mii.fMask = MIIM_STRING;
|
|
#else
|
|
mii.fMask = MIIM_TYPE;
|
|
#endif // MEMPHIS_MENUS
|
|
mii.dwTypeData = lpsz;
|
|
mii.cch = cchMax;
|
|
|
|
if (cchMax)
|
|
lpsz[0] = 0;
|
|
|
|
#ifdef MEMPHIS_MENUS
|
|
if (GetMenuItemInfoInternal(hMenu, wID, (BOOL) (flags & MF_BYPOSITION), &mii)) {
|
|
if (!mii.dwTypeData )
|
|
#else
|
|
if (GetMenuItemInfo(hMenu, wID, (BOOL) (flags & MF_BYPOSITION), &mii))
|
|
{
|
|
if (mii.fType & MFT_NONSTRING)
|
|
#endif // MEMPHIS_MENUS
|
|
return(0);
|
|
return(mii.cch);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
#ifndef MEMPHIS_MENUS
|
|
BOOL GetMenuItemInfo(HMENU hMenu, UINT uID, BOOL fByPosition,
|
|
LPMENUITEMINFO lpInfo)
|
|
{
|
|
PITEM pItem;
|
|
PMENU pMenu;
|
|
|
|
if (lpInfo->cbSize != sizeof (MENUITEMINFO)) {
|
|
RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "GetMenuItemInfo, bad size\n");
|
|
return FALSE;
|
|
}
|
|
|
|
pMenu = VALIDATEHMENU(hMenu);
|
|
|
|
if (pMenu == NULL)
|
|
return FALSE;
|
|
|
|
// Find out where the item we are modifying is.
|
|
pItem = MNLookUpItem(pMenu, uID, fByPosition, &pMenu);
|
|
|
|
if (pItem == NULL)
|
|
return(FALSE);
|
|
|
|
if (lpInfo->fMask & MIIM_STATE)
|
|
lpInfo->fState = pItem->fState & MFS_MASK;
|
|
|
|
if (lpInfo->fMask & MIIM_ID)
|
|
lpInfo->wID = pItem->wID;
|
|
|
|
if (lpInfo->fMask & MIIM_SUBMENU) {
|
|
if (pItem->spSubMenu)
|
|
lpInfo->hSubMenu = PtoH(REBASEPTR(pMenu, pItem->spSubMenu));
|
|
else
|
|
lpInfo->hSubMenu = NULL;
|
|
}
|
|
|
|
if (lpInfo->fMask & MIIM_CHECKMARKS) {
|
|
lpInfo->hbmpChecked = pItem->hbmpChecked;
|
|
lpInfo->hbmpUnchecked= pItem->hbmpUnchecked;
|
|
}
|
|
|
|
if (lpInfo->fMask & MIIM_DATA) {
|
|
lpInfo->dwItemData = pItem->dwItemData;
|
|
}
|
|
|
|
if (lpInfo->fMask & MIIM_TYPE) {
|
|
lpInfo->fType = pItem->fType & MFT_MASK;
|
|
if (pItem->fType & MFT_NONSTRING) {
|
|
lpInfo->dwTypeData = NULL;
|
|
lpInfo->cch = 0;
|
|
if (pItem->fType & MFT_BITMAP) {
|
|
lpInfo->dwTypeData = pItem->hTypeData;
|
|
}
|
|
}else if (lpInfo->cch && (pItem->hTypeData != NULL)) {
|
|
int cch;
|
|
|
|
cch = min(lpInfo->cch - 1, pItem->cch);
|
|
|
|
#if IS_ANSI
|
|
cch = WCSToMB(REBASEPTR(pMenu, pItem->hTypeData), pItem->cch,
|
|
&(lpInfo->dwTypeData), cch, FALSE);
|
|
lpInfo->dwTypeData[cch] = '\0';
|
|
#else
|
|
wcsncpycch(lpInfo->dwTypeData, (LPWSTR)REBASEPTR(pMenu, pItem->hTypeData), cch);
|
|
lpInfo->dwTypeData[cch] = 0;
|
|
#endif
|
|
lpInfo->cch = cch;
|
|
}
|
|
else
|
|
lpInfo->cch = pItem->cch;
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
#else // MEMPHIS_MENUS
|
|
|
|
// ---------------------------------------------------------------------------
|
|
//
|
|
// GetMenuItemInfo() -
|
|
//
|
|
// 1) converts a MENUITEMINFO95 or a new-MENUITEMINFO-with-old-flags to a new
|
|
// MENUITEMINFO -- this way all internal code can assume one look for the
|
|
// structure
|
|
// 2) calls the internal GetMenuItemInfo which performs validation and work
|
|
// 3) converts the new MENUITEMINFO back to the original MENUITEMINFO
|
|
//
|
|
// ---------------------------------------------------------------------------
|
|
|
|
BOOL GetMenuItemInfo(HMENU hMenu, UINT wID, BOOL fByPos, LPMENUITEMINFO lpmii)
|
|
{
|
|
MENUITEMINFO miiNew;
|
|
BOOL fResult;
|
|
|
|
// HACK
|
|
// If MIIM_TYPE is specified in the mask, we need to add MIIM_FTYPE,
|
|
// MIIM_STRING, and MIIM_BITMAP to the mask so that we fill those fields
|
|
if (lpmii->fMask & MIIM_TYPE)
|
|
lpmii->fMask |= MIIM_FTYPE | MIIM_STRING | MIIM_BITMAP;
|
|
|
|
MIIOneWayConvert((LPMENUITEMINFOW)lpmii, (LPMENUITEMINFOW)&miiNew);
|
|
|
|
if (!ValidateMENUITEMINFO((LPMENUITEMINFOW)&miiNew, MENUAPI_GET)) {
|
|
return FALSE;
|
|
}
|
|
|
|
fResult = GetMenuItemInfoInternal(hMenu, wID, fByPos, &miiNew);
|
|
|
|
lpmii->fType = miiNew.fType;
|
|
lpmii->fState = miiNew.fState;
|
|
lpmii->wID = miiNew.wID;
|
|
lpmii->hSubMenu = miiNew.hSubMenu;
|
|
lpmii->hbmpChecked = miiNew.hbmpChecked;
|
|
lpmii->hbmpUnchecked = miiNew.hbmpUnchecked;
|
|
lpmii->dwItemData = miiNew.dwItemData;
|
|
|
|
if (lpmii->fMask & MIIM_TYPE) {
|
|
if (miiNew.hbmpItem) {
|
|
lpmii->dwTypeData = (LPTSTR)miiNew.hbmpItem;
|
|
lpmii->fType |= MFT_BITMAP;
|
|
} else if (!miiNew.cch)
|
|
lpmii->dwTypeData = 0;
|
|
}
|
|
|
|
lpmii->cch = miiNew.cch;
|
|
|
|
return(fResult);
|
|
}
|
|
|
|
#endif // MEMPHIS_MENUS
|
|
|
|
WINUSERAPI LONG BroadcastSystemMessage(DWORD dwFlags, LPDWORD lpdwRecipients,
|
|
UINT uiMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
extern LONG BroadcastSystemMessageWorker(DWORD dwFlags, LPDWORD lpdwRecipients,
|
|
UINT uiMessage, WPARAM wParam, LPARAM lParam, BOOL fAnsi);
|
|
|
|
return BroadcastSystemMessageWorker(dwFlags, lpdwRecipients,
|
|
uiMessage, wParam, lParam, IS_ANSI);
|
|
}
|