📄 w32win32.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
* Unicode <--> MultiByte conversions, OLE, and other system functions
*
*/
class CConvertStr
{
public:
operator char *();
protected:
CConvertStr();
~CConvertStr();
void Free();
LPSTR _pstr;
char _ach[MAX_PATH * 2];
};
inline CConvertStr::operator char *()
{
return _pstr;
}
inline CConvertStr::CConvertStr()
{
_pstr = NULL;
}
inline CConvertStr::~CConvertStr()
{
Free();
}
class CStrIn : public CConvertStr
{
public:
CStrIn(LPCWSTR pwstr);
CStrIn(LPCWSTR pwstr, int cwch);
int strlen();
protected:
CStrIn();
void Init(LPCWSTR pwstr, int cwch);
int _cchLen;
};
inline CStrIn::CStrIn()
{
}
inline int CStrIn::strlen()
{
return _cchLen;
}
class CStrOut : public CConvertStr
{
public:
CStrOut(LPWSTR pwstr, int cwchBuf);
~CStrOut();
int BufSize();
int Convert();
private:
LPWSTR _pwstr;
int _cwchBuf;
};
inline int CStrOut::BufSize()
{
return _cwchBuf * 2;
}
//
// Multi-Byte ---> Unicode conversion
//
class CConvertStrW
{
public:
operator WCHAR *();
protected:
CConvertStrW();
~CConvertStrW();
void Free();
LPWSTR _pwstr;
WCHAR _awch[MAX_PATH * 2];
};
inline CConvertStrW::CConvertStrW()
{
_pwstr = NULL;
}
inline CConvertStrW::~CConvertStrW()
{
Free();
}
inline CConvertStrW::operator WCHAR *()
{
return _pwstr;
}
class CStrInW : public CConvertStrW
{
public:
CStrInW(LPCSTR pstr);
CStrInW(LPCSTR pstr, UINT uiCodePage);
CStrInW(LPCSTR pstr, int cch, UINT uiCodePage);
int strlen();
protected:
CStrInW();
void Init(LPCSTR pstr, int cch, UINT uiCodePage);
int _cwchLen;
UINT _uiCodePage;
};
inline CStrInW::CStrInW()
{
}
inline int CStrInW::strlen()
{
return _cwchLen;
}
class CStrOutW : public CConvertStrW
{
public:
CStrOutW(LPSTR pstr, int cchBuf, UINT uiCodePage);
~CStrOutW();
int BufSize();
int Convert();
private:
LPSTR _pstr;
int _cchBuf;
UINT _uiCodePage;
};
inline int CStrOutW::BufSize()
{
return _cchBuf;
}
ATOM WINAPI CW32System::RegisterREClass(
const WNDCLASSW *lpWndClass,
const char *szAnsiClassName,
WNDPROC AnsiWndProc
)
{
WNDCLASSA wc;
TRACEBEGIN(TRCSUBSYSWRAP, TRCSCOPEINTERN, "RegisterREClass");
// First register the normal window class.
if (VER_PLATFORM_WIN32_WINDOWS != _dwPlatformId)
{
if (!::RegisterClass(lpWndClass))
return NULL;
}
else
{
// On WIndows 95 we need to convert the window class name.
CStrIn strMenuName(lpWndClass->lpszMenuName);
CStrIn strClassName(lpWndClass->lpszClassName);
Assert(sizeof(wc) == sizeof(*lpWndClass));
memcpy(&wc, lpWndClass, sizeof(wc));
wc.lpszMenuName = strMenuName;
wc.lpszClassName = strClassName;
if (!::RegisterClassA(&wc))
return NULL;
}
// Now REgister the ANSI window class name i.e. RICHEDIT20A
wc.style = lpWndClass->style;
wc.cbClsExtra = lpWndClass->cbClsExtra;
wc.cbWndExtra = lpWndClass->cbWndExtra;
wc.hInstance = lpWndClass->hInstance;
wc.hIcon = lpWndClass->hIcon;
wc.hCursor = lpWndClass->hIcon;
wc.hbrBackground = lpWndClass->hbrBackground;
wc.lpszMenuName = NULL;
wc.lpfnWndProc = AnsiWndProc;
wc.lpszClassName = szAnsiClassName;
return ::RegisterClassA(&wc);
}
LRESULT CW32System::WndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
CTxtWinHost *ped = (CTxtWinHost *) GetWindowLong(hwnd, ibPed);
#ifdef DEBUG
Tracef(TRCSEVINFO, "hwnd %lx, msg %lx, wparam %lx, lparam %lx", hwnd, msg, wparam, lparam);
#endif // DEBUG
switch(msg)
{
case WM_NCCREATE:
return CTxtWinHost::OnNCCreate(hwnd, (CREATESTRUCT *) lparam);
break;
case WM_NCDESTROY:
if( ped )
{
CTxtWinHost::OnNCDestroy(ped);
}
return 0;
}
return ped ? ped->TxWindowProc(hwnd, msg, wparam, lparam)
: DefWindowProc(hwnd, msg, wparam, lparam);
}
LONG ValidateTextRange(TEXTRANGE *pstrg);
LRESULT CW32System::ANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
TRACEBEGIN(TRCSUBSYSHOST, TRCSCOPEINTERN, "RichEditANSIWndProc");
#ifdef DEBUG
Tracef(TRCSEVINFO, "hwnd %lx, msg %lx, wparam %lx, lparam %lx", hwnd, msg, wparam, lparam);
#endif // DEBUG
CTxtWinHost * ped = (CTxtWinHost *) GetWindowLong(hwnd, ibPed);
LPARAM lparamNew = 0;
WPARAM wparamNew = 0;
CCharFormat cf;
DWORD cpSelMin, cpSelMost;
LRESULT lres;
switch( msg )
{
case WM_SETTEXT:
{
CStrInW strinw((char *)lparam, CP_ACP);
return RichEditWndProc(hwnd, msg, wparam, (LPARAM)(WCHAR *)strinw);
}
case WM_CHAR:
if( W32->UnicodeFromMbcs((LPWSTR)&wparamNew,
1,
(char *)&wparam,
1,
W32->GetKeyboardCodePage()) == 1 )
{
wparam = wparamNew;
goto def;
}
break;
case EM_SETCHARFORMAT:
if( cf.SetA((CHARFORMATA *)lparam) )
{
lparam = (LPARAM)&cf;
goto def;
}
break;
case EM_GETCHARFORMAT:
RichEditWndProc(hwnd, msg, wparam, (LPARAM)&cf);
// Convert CCharFormat to CHARFORMAT(2)A
if (cf.GetA((CHARFORMATA *)lparam))
return ((CHARFORMATA *)lparam)->dwMask;
return 0;
case EM_FINDTEXT:
case EM_FINDTEXTEX:
{
// we cheat a little here because FINDTEXT and FINDTEXTEX overlap
// with the exception of the extra out param chrgText in FINDTEXTEX
FINDTEXTEXW ftexw;
FINDTEXTA *pfta = (FINDTEXTA *)lparam;
CStrInW strinw(pfta->lpstrText, W32->GetKeyboardCodePage());
ftexw.chrg = pfta->chrg;
ftexw.lpstrText = (WCHAR *)strinw;
lres = WndProc(hwnd, msg, wparam, (LPARAM)&ftexw);
if( msg == EM_FINDTEXTEX )
{
// in the FINDTEXTEX case, the extra field in the
// FINDTEXTEX data structure is an out parameter indicating
// the range where the text was found. Update the 'real'
// [in, out] parameter accordingly.
((FINDTEXTEXA *)lparam)->chrgText = ftexw.chrgText;
}
return lres;
}
break;
case EM_GETSELTEXT:
{
// We aren't told how big the incoming buffer is; only that it's
// "big enough". Since we know we are grabbing the selection,
// we'll assume that the buffer is the size of the selection's
// Unicode data (plus 1 for NULL terminator) in bytes.
WndProc(hwnd, EM_GETSEL, (WPARAM)&cpSelMin,
(LPARAM)&cpSelMost);
CStrOutW stroutw((LPSTR)lparam,
(cpSelMost - cpSelMin + 1)*sizeof(WCHAR),
W32->GetKeyboardCodePage());
return WndProc(hwnd, msg, wparam,
(LPARAM)(WCHAR *)stroutw);
}
break;
case WM_GETTEXT:
{
// comvert WM_GETTEXT to ANSI using EM_GTETEXTEX
GETTEXTEX gt;
gt.cb = wparam;
gt.flags = GT_USECRLF;
gt.codepage = CP_ACP;
gt.lpDefaultChar = NULL;
gt.lpUsedDefChar = NULL;
return WndProc(hwnd, EM_GETTEXTEX, (WPARAM)>, lparam);
}
break;
case WM_GETTEXTLENGTH:
{
// convert WM_GETTEXTLENGTH to ANSI using EM_GETTEXTLENGTHEX
GETTEXTLENGTHEX gtl;
gtl.flags = GTL_NUMBYTES | GTL_PRECISE | GTL_USECRLF;
gtl.codepage = CP_ACP;
return WndProc(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
}
break;
case EM_GETTEXTRANGE:
{
TEXTRANGEA *ptrg = (TEXTRANGEA *)lparam;
LONG clInBuffer = ValidateTextRange((TEXTRANGEW *) ptrg);
// If size is -1, this means that the size required is the total
// size of the the text.
if (-1 == clInBuffer)
{
// We can get this length either by digging the data out of the
// various structures below us or we can take advantage of the
// WM_GETTEXTLENGTH message. The first might be slightly
// faster but the second definitely save code size. So we
// will go with the second.
clInBuffer = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
}
if (0 == clInBuffer)
{
// The buffer was invalid for some reason or there was not data
// to copy. In any case, we are done.
return 0;
}
// Verify that the output buffer is big enough.
if (IsBadWritePtr(ptrg->lpstrText, clInBuffer + 1))
{
// Not enough space so don't copy any
return 0;
}
// For EM_GETTEXTRANGE case, we again don't know how big the incoming buffer is, only that
// it should be *at least* as great as cpMax - cpMin in the
// text range structure. We also know that anything *bigger*
// than (cpMax - cpMin)*2 bytes is uncessary. So we'll just assume
// that's it's "big enough" and let WideCharToMultiByte scribble
// as much as it needs. Memory shortages are the caller's
// responsibility (courtesy of the RichEdit1.0 design).
CStrOutW stroutw( ptrg->lpstrText, (clInBuffer + 1) * sizeof(WCHAR),
CP_ACP );
TEXTRANGEW trgw;
trgw.chrg = ptrg->chrg;
trgw.lpstrText = (WCHAR *)stroutw;
if (WndProc(hwnd, EM_GETTEXTRANGE, wparam, (LPARAM)&trgw))
{
// need to return the number of BYTE converted.
return stroutw.Convert();
}
}
case EM_REPLACESEL:
{
CStrInW strinw((LPSTR)lparam, CP_ACP);
return WndProc(hwnd, msg, wparam, (LPARAM)(WCHAR *)strinw);
}
case EM_GETLINE:
{
// the size is indicated by the first word of the memory pointed
// to by lparam
WORD size = *(WORD *)lparam;
CStrOutW stroutw((char *)lparam, (DWORD)size, CP_ACP);
WCHAR *pwsz = (WCHAR *)stroutw;
*(WORD *)pwsz = size;
return WndProc(hwnd, msg, wparam, (LPARAM)pwsz);
}
case WM_NCCREATE:
case WM_CREATE:
{
// the only thing we need to convert are the strings,
// so just do a structure copy and replace the
// strings.
CREATESTRUCTW csw = *(CREATESTRUCTW *)lparam;
CREATESTRUCTA *pcsa = (CREATESTRUCTA *)lparam;
CStrInW strinwName(pcsa->lpszName, W32->GetKeyboardCodePage());
CStrInW strinwClass(pcsa->lpszClass, CP_ACP);
csw.lpszName = (WCHAR *)strinwName;
csw.lpszClass = (WCHAR *)strinwClass;
return WndProc(hwnd, msg, wparam, (LPARAM)&csw);
}
default:
def: return WndProc(hwnd, msg, wparam, lparam);
}
return 0; // Something went wrong.
}
HGLOBAL WINAPI CW32System::GlobalAlloc( UINT uFlags, DWORD dwBytes )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -