업데이트 : 요청한대로 Window 및 RichEdit 컨트롤을 만드는 데 사용하고있는 코드를 모두 추가했습니다.MSFTEDIT_CLASS (RichEdit) 컨트롤에서 Windows 메시지를 올바르게 처리하는 방법?
다른 창 자식으로 사용되는 RichEdit 컨트롤에 대한 Windows 메시지를 처리하려고합니다.
이제 RichEdit 컨트롤이 내 자신의 WndProc
을 제외하고 작동하게되었습니다. 문제는 wc.lpszClassName = MSFTEDIT_CLASS;
을 CreateWindowEx()
에 사용 된 lpClassName
과 일치하도록 설정하면 더 이상 RichEdit 컨트롤의 내용 (예 : 텍스트 등)이 표시되지 않지만 해당 WndProc 함수가 메시지를 처리 할 수 있다는 것입니다.
윈도우의 생성 :
최초 생성자 :
SubWindow::SubWindow(const wchar_t *szAppNameImport)
{
szAppName = szAppNameImport;
cfmt = CHARFORMATW();
hwnd = HWND();
windowRect = RECT();
editControlHwnd = HWND();
wc = WNDCLASSEX();
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_CLASSDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
wc.hIconSm = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
}
이어서 Create()
기능 :
VOID SubWindow::Create(unsigned int window_startX, unsigned int window_startY, unsigned int windowWidthInput, unsigned int windowHeightInput, HWND parent)
{
windowRect.left = window_startX;
windowRect.top = window_startY;
windowRect.right = windowWidthInput;
windowRect.bottom = windowHeightInput;
if(!RegisterClassEx(&wc))
{
throw std::exception();
}
if((hwnd = CreateWindowEx
(
WS_EX_CLIENTEDGE,
szAppName,
TEXT("Our classy sub window!"),
WS_OVERLAPPEDWINDOW| WS_VISIBLE,
windowRect.left, windowRect.top,
windowRect.right, windowRect.bottom,
parent,
NULL,
wc.hInstance,
NULL))==NULL)
{
throw std::exception();
}
SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)this);
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
}
의 WndProc :
LRESULT CALLBACK SubWindow::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SubWindow *childWindowPointer = (SubWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(childWindowPointer != NULL)
{
if(childWindowPointer->GetEditControl() == hwnd)
OutputDebugString(L"I SHOULD NOT BE CALLED");
return childWindowPointer->MsgProc(hwnd, uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
MsgPr OC :
LRESULT SubWindow::MsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(uMsg)
{
case WM_WINDOWPOSCHANGED:
{
GetClientRect(hwnd, &windowRect);
SetWindowPos(editControlHwnd, NULL, windowRect.left, windowRect.top, windowRect.right, windowRect.bottom, SWP_NOZORDER | SWP_NOACTIVATE);
return 0;
}
case WM_DESTROY:
{
OutputDebugString(TEXT("DESTROYING A SUB WINDOW!\n"));
return 0;
}
case WM_PAINT:
{
InvalidateRect (hwnd, NULL, FALSE);
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
}
case EM_EXSETSEL:
{
if(hwnd == editControlHwnd)
{
OutputDebugString(L"Text selection changed");
return 0;
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
RichEdit 컨트롤은 내가 정의한 WndProc
를 사용하지 않고, 분명히 문제없이, 무 완벽하게 작동합니다.
내가 잘못하고있는 것이 무엇인지, 올바르게 해결할 수 있는지 잘 모르겠습니다. 편집
: 답변과 의견을 바탕으로 , 나는 RichEdit 컨트롤을 포함 만 Window
클래스를 사용하려면 코드를 복원 한 thusly 히 만든 :
void SubWindow::CreateEditControl()
{
std::wstring initialText = TEXT("TestWindow\r\n");
LoadLibrary(L"Msftedit.dll");
GetClientRect(hwnd, &windowRect);
editControlHwnd = CreateWindowEx(0, MSFTEDIT_CLASS, initialText.data(),
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY | WS_VSCROLL | ES_NOHIDESEL,
windowRect.left, windowRect.top,windowRect.right,windowRect.bottom,
hwnd,
NULL, NULL, NULL);
cfmt.cbSize = sizeof(CHARFORMAT);
cfmt.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE;
cfmt.dwEffects = 0;
cfmt.yHeight = 160;
cfmt.crTextColor = RGB(0,0,0);
wcscpy_s(cfmt.szFaceName, TEXT("Tahoma"));
SendMessage(editControlHwnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cfmt);
}
가 어떻게에서 메시지를 처리 할 창 MsgProc 에서이 컨트롤?
'MSFTEDIT_CLASS'라는 이름으로 자신의 클래스를 등록하면 효과적으로 원본을 대체합니다. 이 작업을 완료하면 원래 클래스에 더 이상 액세스 할 수 없으며 대신 'MSFTEDIT_CLASS'를 만들면 클래스가 생성됩니다. 이것은 한 파일을 다른 파일로 덮어 쓰는 것과 같습니다. 목표가 무엇인지는 분명하지 않습니다. 리치 에디트 컨트롤을 부분적으로 대체하고 싶습니까? 하나의 창만 들어 봤어? 아니면 단순히 창문에서 메시지 *에 응답하려고합니까? –
하나 이상의 윈도우에서 하나의 RichEdit 컨트롤을 만들려고했지만, 지금은 하나뿐입니다. – Interminable
그런 다음 표준 'MSFTEDIT_CLASS'를 만듭니다. 나 자신을 쓰려고하지 마라. 말했듯이 표준 컨트롤을 사용하면 "RichEdit 컨트롤이 완벽하게 작동하고 완벽하게 작동합니다." –