2014-06-14 1 views
0

부모 창 상단에 세 개의 컨트롤이 있습니다. 하나는 사용자 입력을 허용하고 다른 입력은 이전 입력을 표시합니다. 세 번째는 입력 편집 컨트롤의 텍스트를 출력 컨트롤에 추가하는 버튼입니다. 그러나 이렇게하기가 번거롭기 때문에이 작업을 수행하기 위해 '입력'키의 핸들을 추가하고 싶습니다. 현재, 입력 편집 컨트롤을 서브 클래 싱했습니다. 그러나 어떤 switch 문을 구현했는지에 관계없이 입력 컨트롤에서 'WM_KeyDown'메시지를 해석 할 수 없습니다. 그러나 부모 컨트롤에 포커스가 있으면 부모 컨트롤에서 전송됩니다. 포커스가있는 경우에도 편집 컨트롤에서 전송되지 않습니다. 나는 이미 여러 가지 해결책을 찾았지만 아직까지는 아무런 해결책도 없다.서브 클래 싱 된 컨트롤 만 상위 메시지 받기

도움이 될 것입니다.

에서 Win32 C++ 2012

#include <Windows.h> 
#include <string.h> 
#include <tchar.h> 
#include <stdlib.h> 
#include <Commctrl.h> 

#include "resource.h" 
#include "Processing.h" 

static TCHAR WinClass[]=_T("SAPA"); 
static TCHAR WinTitle[]=_T("SAPA"); 

HWND InText, OutText, Send; 
LPWSTR string; 

LPTSTR buff = new TCHAR [1024]; 
LPTSTR Tbuff = new TCHAR [1024]; 

HINSTANCE hInst; 

syscore sysCore; 

WNDPROC DefProc; 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); 
DWORD dwRefData; 
UINT uIdSubClass; 

int WINAPI WinMain(HINSTANCE hIn, HINSTANCE hpIn, LPSTR CmdLine, int CmdShow) 
{ 
WNDCLASSEX wcex; 

wcex.cbSize   = sizeof(WNDCLASSEX); 
wcex.style   = CS_HREDRAW | CS_VREDRAW; 
wcex.lpfnWndProc = WndProc; 
wcex.cbClsExtra  = 0; 
wcex.cbWndExtra  = 0; 
wcex.hInstance  = hIn; 
wcex.hIcon   = LoadIcon(hIn,MAKEINTRESOURCE(APP_ICO)); 
wcex.hCursor  = LoadCursor(NULL,IDC_ARROW); 
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
wcex.lpszMenuName = L"IDC_WINMENU"; 
wcex.lpszClassName = WinClass; 
wcex.hIconSm   = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(APP_ICO)); 

if (!RegisterClassEx(&wcex)) 
{ 
    MessageBox(NULL,_T("RegClassEx Failure"),_T("ERROR"),NULL); 
    return 1; 
} 

hInst=hIn; 

HWND hwnd=CreateWindow(WinClass, WinTitle,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 800,650,NULL,NULL, hIn,NULL); 

if (!hwnd) 
{ 
    MessageBox(NULL,_T("CreateWindow Failuer"),_T("ERROR"),NULL); 
    return 1; 
} 

ShowWindow(hwnd, CmdShow); 

UpdateWindow(hwnd); 

MSG msg; 
while(GetMessage(&msg,NULL,0,0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

return (int) msg.wParam; 

} 

LRESULT CALLBACK InEditControlProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) 
{ 
// if (LOWORD(wp)==IDM_IN) 
    switch(msg) { 
    case WM_COMMAND: 
     if (LOWORD(wp)==IDM_IN) 
      if (HIWORD(wp)==WM_KEYDOWN) 
       if (HIWORD(lp)==VK_LCONTROL) 
        PostQuitMessage(0); 
     break; 
     case WM_KEYDOWN: { 
     switch (wp) { 
      case VK_RETURN: { 
       PostQuitMessage(0); 
        //simulate a button press, see below 
        // return 0;//if the procedure responds the action, finish the control procedure 
        break; 
       } 
       break; 
      } 
     } 
     break; 
      //return CallWindowProc(WndProc,hwnd,msg,wp,lp);//WndProc(hwnd,msg,wp,lp); 
     default: 
     return CallWindowProc(WndProc,hwnd,msg,wp,lp);//WndProc(hwnd,msg,wp,lp); 
     //return WndProc(hwnd,msg,wp,lp); 
    } 
    return 0; 
} 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) 
{ 
    int len=0; 
    //LPCWSTR buffer=L""; 
    switch (msg) 
    { 
    case WM_CREATE: 
     OutText=CreateWindow(L"edit", L"",ES_READONLY|ES_MULTILINE|WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOVSCROLL, 0, 0, 800,550,hwnd,(HMENU)IDM_OUT, NULL,NULL); 
     InText=CreateWindow(L"edit", L"",WS_CHILD|WS_VISIBLE|WS_BORDER, 0, 550, 720,50,hwnd,(HMENU)IDM_IN, NULL,NULL); 
     Send=CreateWindow(L"button", L"SEND",WS_CHILD|WS_VISIBLE|WS_BORDER, 720, 550, 80,25,hwnd,(HMENU)MSG_SEND, NULL,NULL); 
     CreateWindow(L"button", L"CLEAR",WS_CHILD|WS_VISIBLE|WS_BORDER, 720, 575, 80,25,hwnd,(HMENU)IDM_CLEAR, NULL,NULL); 

     //DefProc = (WNDPROC)GetWindowLong(hwnd,GWL_WNDPROC); 
     //SetWindowLong(hwnd,GWL_WNDPROC,(LONG_PTR)InEditControlProc); 
     DefProc=(WNDPROC)SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)InEditControlProc); 
     //SetWindowSubclass(hwnd,InEditControlProc,uIdSubClass,dwRefData); 
     ShowWindow(InText,SW_SHOW); 
     SetFocus(InText); 

     startup(hwnd,OutText,InText,sysCore); 
     break; 
    case WM_DESTROY: 
     SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)WndProc); 
     PostQuitMessage(0); 
     break; 
    case WM_COMMAND: 

     switch (LOWORD(wp)) 
     { 
     case MSG_SEND: 
      //TCHAR buff[1024]; 
      buff = new TCHAR [1024]; 
      Tbuff = new TCHAR [1024]; 
      GetWindowText(GetDlgItem(hwnd,IDM_IN),buff,1024);//get text from box, store to buffer 
      GetWindowText(GetDlgItem(hwnd,IDM_OUT),Tbuff,1024);//retain window text 
      SetWindowText(GetDlgItem(hwnd,IDM_IN),L"");//clear field 
      if (buff!=L"")//dont pass if buffer empty 
      { 
      AppendText(hwnd,buff); 
      AppendText(hwnd,L"\r\n"); 
      } 
      handleInput(hwnd,buff,sysCore); 
      //SetWindowText(GetDlgItem(hWnd,OFIELD),buff);//set text 
      delete buff,Tbuff; 
      break; 
     case IDM_CLEAR: 
      SetWindowText(GetDlgItem(hwnd,IDM_OUT),L""); 
      break; 
     case IDM_ABOUT: 
      MessageBox(hwnd,L"App information",L"About",0); 
      break; 
     case IDM_EXIT: 
      PostQuitMessage(0); 
     } 

    default: 
     return DefWindowProc(hwnd, msg,wp,lp); 
     break; 
    } 
    return 0; 
} 
+0

부모에게 전달해야하는 메시지가 표시되면 고려해야 할 첫 번째 가능성은 잘못된 창을 하위 클래스로 분류 한 것입니다. SetWindowLongPtr()에 전달한 윈도우 핸들을 살펴 보겠습니다. 그건 InText가 아니야. –

+0

그렇지 않나요? SetWindowLongPtr()에 전달 된 LONG_PTR 매개 변수는 InText 창 전용 HMENU입니다. hwnd 매개 변수를 InText로 설정하면 InText 창이 비활성화되는 문제가 발생하여 궁극적으로 신호를 보내지 못하게됩니다. – knoxaramav2

답변

0

확인 Visual Studio에서 둘러보고 몇 일 후, 나는 스파이 ++ 유틸리티를 사용하여 학습에 부분적으로 많이 그것을 알아 냈다.

나는 서브 클래스 후, 후/DispatchMessage 이러한 사용자 정의 신호가 올바른 절차에 라우팅 될 수 있습니다 번역 메시지 펌프에 선

if(msg.message==WM_KEYDOWN) 
    SendMessage(hwnd,msg.message,msg.wParam,msg.lParam); 

을 추가하는 것을 발견했다.