Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
winapi C++;处理焦点 我正在研究一个C++ WiNAPI应用程序,我正在努力让 StFixCube()/Cuth>为我工作。我使用WS|u OVERLAPPEDWINDOW | WS|u VISIBLE创建主窗口,然后在其中使用WS|u CHILD | WS|u VISIBLE创建它的子窗口(几个按钮和我自己版本的编辑控件的开头),这些子窗口除了焦点问题之外都可以正常工作_C++_Winapi_Setfocus_Wndproc - Fatal编程技术网

winapi C++;处理焦点 我正在研究一个C++ WiNAPI应用程序,我正在努力让 StFixCube()/Cuth>为我工作。我使用WS|u OVERLAPPEDWINDOW | WS|u VISIBLE创建主窗口,然后在其中使用WS|u CHILD | WS|u VISIBLE创建它的子窗口(几个按钮和我自己版本的编辑控件的开头),这些子窗口除了焦点问题之外都可以正常工作

winapi C++;处理焦点 我正在研究一个C++ WiNAPI应用程序,我正在努力让 StFixCube()/Cuth>为我工作。我使用WS|u OVERLAPPEDWINDOW | WS|u VISIBLE创建主窗口,然后在其中使用WS|u CHILD | WS|u VISIBLE创建它的子窗口(几个按钮和我自己版本的编辑控件的开头),这些子窗口除了焦点问题之外都可以正常工作,c++,winapi,setfocus,wndproc,C++,Winapi,Setfocus,Wndproc,在我的搜索中,我一直在努力寻找更多关于如何处理焦点的信息。当所有窗口都被创建时,它们分别收到WM_SETFOCUS消息,我在编辑控件中通过添加插入符号来处理此消息,但是孩子们似乎从未收到WM_KILLFOCUS消息,因此插入符号从未被销毁 这就是我的问题所在:我希望主父窗口最初有焦点,并且在我的编辑控件中没有插入符号,然后当单击子编辑控件时,它有焦点,然后当单击主窗口时,它应该再次有焦点,依此类推 因此,我最初的想法是在处理WM\u CREATE消息时使用SetFocus()将焦点设置到主窗口,

在我的搜索中,我一直在努力寻找更多关于如何处理焦点的信息。当所有窗口都被创建时,它们分别收到
WM_SETFOCUS
消息,我在编辑控件中通过添加插入符号来处理此消息,但是孩子们似乎从未收到
WM_KILLFOCUS
消息,因此插入符号从未被销毁

这就是我的问题所在:我希望主父窗口最初有焦点,并且在我的编辑控件中没有插入符号,然后当单击子编辑控件时,它有焦点,然后当单击主窗口时,它应该再次有焦点,依此类推

因此,我最初的想法是在处理
WM\u CREATE
消息时使用
SetFocus()
将焦点设置到主窗口,但这似乎不起作用:孩子没有收到
WM\u KILLFOCUS
消息

我的下一个想法是,也许家长必须处理将WM_KILLFOCUS传递给适当的孩子的问题,所以我为我写了一个方法,但孩子们仍然没有收到
WM_KILLFOCUS
消息

因此,我最好的猜测是我在WndProc中没有正确处理消息

我已经创建了自己的窗口类,并通过以下WndProc将消息分发到相应的类:

LRESULT CALLBACK CBaseWindow::stWinMsgHandler(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam,  
    LPARAM lParam)
{
    CBaseWindow* pWnd;

    if (uMsg == WM_NCCREATE)
    {       
        SetWindowLong(hwnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
    }

    pWnd = GetObjectFromWindow(hwnd);

    if (pWnd)
        return pWnd->WinMsgHandler(hwnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
然后每个类都有自己的WndProc,我在其中处理传入的消息

有人对我有什么想法吗

如果我这样做是完全错误的,或者如果我没有遵循最佳实践,请说出来,我这样做是为了学习,所以就开枪吧

[更新]

好的,下面是一些代码来演示问题:

Main.cpp MainWnd.cpp CustomTextBox.cpp 发现 在编写这段代码的过程中,我遇到了问题的原因之一:在我的实际应用程序中,我没有标题栏,因此要将我发送的窗口
WM\u nbuttondown
移动到我的主窗口
WM\u LBUTTONDOWN

SendMessage(hwnd,WM\nclubuttondown,HTCAPTION,NULL)

然后,我的
SetFocus()
在这之后就不起作用了,但是如果我先切换它们并处理
SetFocus()
,那么单击会改变焦点


不过,初始设置焦点仍然存在问题。启动应用程序后,自定义编辑控件仍会显示插入符号,即使它没有焦点,您需要单击它以使其具有焦点,从而它将接收键盘输入。在此之后,焦点按预期工作:如果我点击主窗口,它就有焦点;如果我点击自定义编辑,它会有焦点等。

确定,所以我的整个问题都在于那行
发送消息(hwnd,WM\nclubuttondown,HTCAPTION,NULL)一旦我切换这个:

case WM_LBUTTONDOWN:                        
    SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL);       
    SetFocus(hwnd);
break;
致:


一切都在一起。

请发布一个完整的示例来演示这个问题。WM_KILLFOCUS总是在窗口即将失去焦点时发送到窗口。因此,您的代码中可能有错误。另一件事-您是否尝试将WS_TABSTOP样式添加到子窗口?尝试从测试应用程序中删除所有特定于焦点的(添加的)代码,并查看默认情况下焦点是如何工作的。如果它能工作,那么你似乎做了一些过度的事情,要么阻碍正常的聚焦处理,要么连续做两次——也就是说,你聚焦的只是非聚焦控制,反之亦然。如果不起作用,则您以错误的方式创建了父窗口或控件。@aleguna我发布了描述我的问题的代码,并向子窗口添加了
WS_TABSTOP
,但它仍然不能完全起作用@Stan我试图删除所有特定于焦点的代码,但仍然无法正常工作。如果你阅读我上面的更新,你会看到我几乎所有的代码。希望我们能找出我的错误所在。谢谢你的帮助OK我已经解决了移动窗口和关注点击的问题。只是现在开始设定焦点才是一个问题。
 #include "BaseWindow.h"

 //...

 LRESULT CALLBACK CBaseWindow::stWinMsgHandler(
       HWND hwnd, 
       UINT uMsg, 
       WPARAM wParam, 
       LPARAM lParam)
 {
       CBaseWindow* pWnd;

       if (uMsg == WM_NCCREATE)
       {        
             SetWindowLong(hwnd, 
                  GWL_USERDATA, 
                  (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
   }

        pWnd = GetObjectFromWindow(hwnd);

       if (pWnd)
             return pWnd->WinMsgHandler(hwnd, uMsg, wParam, lParam);
       else
             return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }

 BOOL CBaseWindow::Create(DWORD dwStyles, RECT* rect)
 {  
      m_hwnd = CreateWindow(        
           szClassName, 
           szWindowTitle, 
           dwStyles, 
           rect->left, 
           rect->top, 
           rect->right - rect->left, 
           rect->bottom - rect->top, 
           NULL, 
           NULL, 
           hInstance, 
           (void *)this);   

     return (m_hwnd != NULL);
 }
#include "MainWnd.h"
#define WIDTH 400
#define HEIGHT 400

MainWnd::MainWnd(HINSTANCE hInst): CBaseWindow(hInst), hInstance(hInst)
{
     SetWindowTitle(_T("Main Window"));

     WNDCLASSEX wcx;
     FillWindowClass(&wcx);                 

     if(RegisterWindow(&wcx))
     {      
         RECT rc;
     BuildRect(&rc);

         if(Create(WS_OVERLAPPEDWINDOW | WS_VISIBLE, &rc))
         {          
               customTextBox = new CustomTextBox(hInst, m_hwnd);            
         }
     }  
 }

 void MainWnd::FillWindowClass(WNDCLASSEX *wcx)
 {
      wcx->cbSize = sizeof(WNDCLASSEX);
      wcx->style = CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW;                     
      wcx->lpfnWndProc = CBaseWindow::stWinMsgHandler;          
      wcx->cbClsExtra = 0;                                      
      wcx->cbWndExtra = 0;                                      
      wcx->hInstance = hInstance;                                   
      wcx->hIcon = LoadIcon(NULL, IDI_APPLICATION);             
      wcx->hCursor = LoadCursor(NULL, IDC_ARROW);
      wcx->hbrBackground = CreateSolidBrush(RGB(255,255,255));      
      wcx->lpszMenuName = NULL;                                 
      wcx->lpszClassName = _T("MainWindow");
      wcx->hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 }

 LRESULT CALLBACK MainWnd::WinMsgHandler(
       HWND hwnd, 
       UINT uMsg, 
       WPARAM wParam, 
       LPARAM lParam)
 {          
       switch (uMsg)
       {
       case WM_DESTROY:
            delete customTextBox;
            PostQuitMessage(0);     
            break;
       case WM_LBUTTONUP:
            SetFocus(hwnd);
            break;
       default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
       }
       return 0;
 }
 #include "CustomTextBox.h"

 CustomTextBox::CustomTextBox(
      HINSTANCE hInst, 
      HWND hParent): CBaseWindow(hInst), 
                 hParent(hParent),
 {  
      WNDCLASSEX wcx;
      CreateWndClassEX(wcx);
      if(RegisterWindow(&wcx))
      {
           RECT clientRect;
           CreateClientRect(clientRect);
           CreateChild(WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, &clientRect, hParent);       
      }
 }

 void CustomTextBox::CreateWndClassEX(WNDCLASSEX& wcx)
 {
      wcx.cbSize = sizeof(WNDCLASSEX);
      wcx.style = CS_HREDRAW | CS_VREDRAW;    
      wcx.lpfnWndProc = CBaseWindow::stWinMsgHandler;
      wcx.cbClsExtra = 0;                                           
      wcx.cbWndExtra = 0;
      wcx.hInstance = hInstance;
      wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
      wcx.hbrBackground = CreateSolidBrush(RGB(255,255,255));
      wcx.lpszMenuName = NULL;
      wcx.lpszClassName = _T("Edit Control");
      wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 }

 LRESULT CALLBACK CustomTextBox::WinMsgHandler(
      HWND hwnd, 
      UINT uMsg, 
      WPARAM wParam, 
      LPARAM lParam)
 {
      switch(uMsg)
      {
      /* Handling the caret */
      case WM_SETFOCUS:
           CreateCaret(hwnd, NULL, 0, nWindowY); 
           SetCaretPos(GetEndOfLinePoint(), nCaretPosY * nCharY); 
           ShowCaret(hwnd); 
           return 0;    
      case WM_MOUSEACTIVATE:
           SetFocus(hwnd);
           return MA_ACTIVATE;
      case WM_KILLFOCUS:
           DestroyCaret();
           return 0;
      default:
           return DefWindowProc(hwnd, uMsg, wParam, lParam);
      }         
 }
case WM_LBUTTONDOWN:                        
    SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL);       
    SetFocus(hwnd);
break;
case WM_LBUTTONDOWN:                        
    SetFocus(hwnd);
    SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL);
break;