C++ Builder 2009 - Cannot focus a disabled or invisible window

我只是一个虾纸丫 提交于 2019-12-12 16:41:46

问题


I've been refactoring an old project. I found when the old programmers tried to use the SetFocus() of TWinControls they surrounded them in try/catches with empty catch blocks. Thus swallowing the exceptions.

The default behavior of the program is to set the focus if the control is enabled. In order to do that I created a function which I can pass the TWinControl to:

void SafeSetFocus(TWinControl *Control)
{
    if(Control->Enabled && Control->Visible)
    {
        Control->SetFocus();
    }
}

This code works for most of the program, however I found that in one area that I still get a Debugger Exception of Cannot focus a disabled or invisible window.

I thought that the issue might be related to the parent, so I tried the following adjustment:

void SafeSetFocus(TWinControl *Control)
{
    if(Control->Enabled && Control->Visible &&
            Control->Parent->Enabled && Control->Parent->Visible)
    {
        Control->SetFocus();
    }
}

This changed did not solve the issue. Because of this, I realized that the window may not necessarily be the parent. So my question boils down to:

Is there a way to determine what the window of the TWinControl is and check to see if it is visible? This assumes the exception is accurate... otherwise if you know what the issue is, please share your knowledge :)


Additional Troubleshooting Notes, Part 1:

I've tried to determine the class name of the ParentWindow by the following code:

String parentWindowClassName = ((TObject *)(Control->ParentWindow))->ClassName();
MessageDlg("parentWindowClassName: " + parentWindowClassName, mtInformation, TMsgDlgButtons() << mbOK, 0);

The first line of code gives an access violation when I run it... any thoughts on a different way to try to determine the info?

Additional Troubleshooting Notes, Part 2:

CanFocus() with just the control doesn't work. CanFocus() for the control and parent doesn't work, see screen shot.


回答1:


There is a much simplier solution - call the TWinControl::CanFocus() method before calling TWinControl::SetFocus():

void SafeSetFocus(TWinControl *Control)
{
    if (Control->CanFocus())
        Control->SetFocus();
}



回答2:


Thanks goes out to @KenWhite for his suggestions in question ( C++ Builder 2009 - How to Determine if Control's Window is Visible )

His suggestions in that question lead me to the answer. Below is the code others might be interested in:

#include "winuser.h"

...

void SafeSetFocus(TWinControl *Control)
{
    THandle* hWnd = (THandle *)(Control->ParentWindow);
    bool parentIsVisible = IsWindowVisible(hWnd);

    if(Control->Enabled && Control->Visible && parentIsVisible)
    {
        Control->SetFocus();
    }
}



回答3:


Improving on James Oravec's answer. I just changed:

bool parentIsVisible = IsWindowVisible(hWnd);

to:

bool parentIsVisible = IsWindowVisible((HWND__*)hWnd);


来源:https://stackoverflow.com/questions/15444418/c-builder-2009-cannot-focus-a-disabled-or-invisible-window

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!