GithubHelp home page GithubHelp logo

Comments (35)

PBfordev avatar PBfordev commented on June 3, 2024 1

mojie126, that is not what you were asked for. The code is neither smallest nor complete (i.e., can be compiled as is). You also obviously don't use DIPs for sizes and positions when creating the controls (maybe a limitation of of Code::Smith).

But actually, there is an issue. When using hard-coded sizes, unlike wxTextCtrl, wxChoice may not respect too big height (but its height is still tall enough to fit its text comfortably). For example, when creating the controls using height FromDIP(30) at 125% DPI scaling, I get

DPI scaling: 1.25
text ctrl height: 38, choice height: 28

Once again, this demonstrates why hard-coded sizes should be avoided and sizers used instead.

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

I assume you meant to say that the height of wxChoice is too low (e.g., compared to wxTextCtrl) in high DPI?

If so, I cannot reproduce it.
100% DPI
wx-choice-textctrl100
175% DPI
wx-choice-textctrl

result of running as Per Monitor v2 DPI-aware

#include <wx/wx.h>

class MyApp : public wxApp
{
    bool OnInit() override
    {
        wxFrame* frame = new wxFrame(nullptr, wxID_ANY, "Test");
        wxPanel* panel = new wxPanel(frame);
        wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);

        sizer->Add(new wxStaticText(panel, wxID_ANY, "static text"), wxSizerFlags().Border().CenterVertical());
        sizer->Add(new wxTextCtrl(panel, wxID_ANY, "text ctrl"), wxSizerFlags().Border().CenterVertical());

        wxChoice* choice = new wxChoice(panel, wxID_ANY);
        choice->Append("choice");
        choice->Select(0);
        sizer->Add(choice, wxSizerFlags().Border().CenterVertical());

        sizer->Add(new wxButton(panel, wxID_ANY, "button"), wxSizerFlags().Border().CenterVertical());
        sizer->Add(new wxCheckBox(panel, wxID_ANY, "check box"), wxSizerFlags().Border().CenterVertical());

        panel->SetSizerAndFit(sizer);
        frame->Fit();
        frame->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

Unfortunately, you did not provide any useful information that could help explain the difference. Are you sure you are not using a hardcoded pixel size for your control? If so, and if you really, REALLY must use an exact size instead of relying on autosizing, make sure to use at least FromDIP(). Better yet, for controls using text, use a size based on the font size (see e.g., wxControl::GetSize*() methods).

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

Yes, 100%DPI and 200%DPI have different styles for these two controls. The text will stick to the upper edge.
Judging from your sample code, I don't use Sizer. Does this have anything to do with it?

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

Also I used FromDIP()

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

And I defined the size and position when using new

from wxwidgets.

vadz avatar vadz commented on June 3, 2024

Please provide the smallest possible example reproducing the problem, similar to the example above (thanks, PB!).

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

Once again, the age-old advice is: Do not use hardcoded sizes and positions. This is bound to break sooner or later. It could have never worked not only across the platforms, but also for a custom user setting within the same OS (e.g, using a non-default GUI font).

That being said, I did a simple test using hardcoded sizes for wxTextCtrl and wxComboCtrl:

#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
    MyFrame(wxWindow* parent = nullptr) : wxFrame(parent, wxID_ANY, "Test")
    {
        wxPanel* panel = new wxPanel(this);

        const size_t ctlHeight = FromDIP(20);
        const size_t ctlWidth = FromDIP(50);
        const int ctlY = FromDIP(5);
        int ctlX = FromDIP(5);

        m_choice = new wxChoice(panel, wxID_ANY, wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));
        ctlX += ctlWidth + FromDIP(5);
        m_textCtrl = new wxTextCtrl(panel, wxID_ANY, "", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        m_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&)
            {
                wxLogDebug("DPI scaling: %.2f", GetDPIScaleFactor());
                wxLogDebug("text ctrl height: %d, choice height: %d", m_textCtrl->GetSize().y, m_choice->GetSize().y);

            });
        m_timer.StartOnce(1000);
    }
private:
    wxChoice* m_choice;
    wxTextCtrl* m_textCtrl;
    wxTimer m_timer;
};

class MyApp : public wxApp
{
    bool OnInit() override
    {
        (new MyFrame)->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

The control heights are (1) matching each other when run on 100% and 200% DPI and (2) match the values used when creating them (i.e., 20 px in 100% DPI and 20 px in 200% DPI).

If you really want help, you need to provide the smallest complete reproducible code, i.e., the same I have done in my posts here. You should also run the code I provided unchanged and report whether you get the same results as I did.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024
bool SuperBDXApp::OnInit() {
	//(*AppInitialize
	bool wxsOK = true;
	wxInitAllImageHandlers();
	if (wxsOK) {
		SuperBDXDialog Dlg(nullptr);
		SetTopWindow(&Dlg);
		//设置图标
		Dlg.SetIcon(wxIcon("aaaa"));
		//开启双缓冲
		Dlg.SetDoubleBuffered(true);
		Dlg.OnUpdateUIFromDIP();
		Dlg.ShowModal();
		wxsOK = false;
	}
	//*)
	return wxsOK;
}
void SuperBDXDialog::OnUpdateUIFromDIP() {
	Choice1->SetSize(FromDIP(58), FromDIP(320), FromDIP(115), FromDIP(25));
}
SuperBDXDialog::SuperBDXDialog(wxWindow *parent, wxWindowID id) {
	wxChoice* Choice1= new wxChoice(this, ID_CHOICE1, wxPoint(58, 320), wxSize(115, 25), 0, 0, 0, wxDefaultValidator, _T("ID_CHOICE1"));
}

I created it using Code::Blocks

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

Once again, the age-old advice is: Do not use hardcoded sizes and positions. This is bound to break sooner or later. It could have never worked not only across the platforms, but also for a custom user setting within the same OS (e.g, using a non-default GUI font).

That being said, I did a simple test using hardcoded sizes for wxTextCtrl and wxComboCtrl:

#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
    MyFrame(wxWindow* parent = nullptr) : wxFrame(parent, wxID_ANY, "Test")
    {
        wxPanel* panel = new wxPanel(this);

        const size_t ctlHeight = FromDIP(20);
        const size_t ctlWidth = FromDIP(50);
        const int ctlY = FromDIP(5);
        int ctlX = FromDIP(5);

        m_choice = new wxChoice(panel, wxID_ANY, wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));
        ctlX += ctlWidth + FromDIP(5);
        m_textCtrl = new wxTextCtrl(panel, wxID_ANY, "", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        m_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&)
            {
                wxLogDebug("DPI scaling: %.2f", GetDPIScaleFactor());
                wxLogDebug("text ctrl height: %d, choice height: %d", m_textCtrl->GetSize().y, m_choice->GetSize().y);

            });
        m_timer.StartOnce(1000);
    }
private:
    wxChoice* m_choice;
    wxTextCtrl* m_textCtrl;
    wxTimer m_timer;
};

class MyApp : public wxApp
{
    bool OnInit() override
    {
        (new MyFrame)->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

The control heights are (1) matching each other when run on 100% and 200% DPI and (2) match the values used when creating them (i.e., 20 px in 100% DPI and 20 px in 200% DPI).

If you really want help, you need to provide the smallest complete reproducible code, i.e., the same I have done in my posts here. You should also run the code I provided unchanged and report whether you get the same results as I did.

Your code is indeed normal when I test it locally.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

mojie126, that is not what you were asked for. The code is neither smallest nor complete (i.e., can be compiled as is). You also obviously don't use DIPs for sizes and positions when creating the controls (maybe a limitation of of Code::Smith).

But actually, there is an issue. When using hard-coded sizes, unlike wxTextCtrl, wxChoice may not respect too big height (but its height is still tall enough to fit its text comfortably). For example, when creating the controls using height FromDIP(30) at 125% DPI scaling, I get

DPI scaling: 1.25
text ctrl height: 38, choice height: 28

Once again, this demonstrates why hard-coded sizes should be avoided and sizers used instead.

Okay, I used codeblock to generate the style code, and input the parameters on the GUI to design it. I didn’t use a sizer for layout at the beginning. It seems that the transformation is a bit difficult.
sad

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

I think wxChoice ignoring the user height may be the limitation of the native control, not a wxWidgets bug.

Using this pure Win32 code, it seems a combobox ignores all attempts to create or size it at too tall or too short height, it just stays at the height it thinks best. AFAICT, it has nothing to do with DPI scaling.
win32-edit-combobox

Win32 code
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>

void FatalError(LPCTSTR errorMessage)
{
    MessageBox(nullptr, errorMessage, _T("Fatal error"), MB_OK | MB_ICONERROR);
    exit(-1);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if ( message == WM_DESTROY )
    {
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
    INITCOMMONCONTROLSEX icex;

    icex.dwSize = sizeof(icex);
    icex.dwICC = ICC_STANDARD_CLASSES;
    if ( !InitCommonControlsEx(&icex) )
        FatalError(_T("Could not init common controls."));

    LPCTSTR className = _T("TestFrame");

    WNDCLASSEX wcex;

    ZeroMemory(&wcex, sizeof(wcex));
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc    = WndProc;
    wcex.hInstance      = hInstance;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszClassName  = className;

    if ( !RegisterClassEx(&wcex) )
        FatalError(_T("Could not register the class for the application window."));

    HWND hFrame = CreateWindow(className, _T("Test"), WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, nullptr, nullptr, hInstance, nullptr);
    if ( !hFrame )
        FatalError(_T("Could not create the application window."));

    const int ctlHeight = 50;
    const int ctlWidth = 100;
    const int ctlY = 5;
    int ctlX = 5;

    HWND hEdit = CreateWindow(WC_EDIT, _T(""), ES_LEFT | WS_CHILD | WS_BORDER | WS_VISIBLE,
                   ctlX, ctlY, ctlWidth, ctlHeight, hFrame, nullptr, hInstance, nullptr);
    if ( !hEdit )
        FatalError(_T("Could not create the edit."));

    ctlX += ctlWidth + 5;
    HWND hComboBox = CreateWindow(WC_COMBOBOX, _T(""), CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_BORDER | WS_VISIBLE,
                         ctlX, ctlY, ctlWidth, ctlHeight, hFrame, nullptr, hInstance, nullptr);
    if ( !hComboBox )
        FatalError(_T("Could not create the combo box."));
    SetWindowPos(hComboBox, nullptr, ctlX, ctlY, ctlWidth, ctlHeight, SWP_NOZORDER);

    ShowWindow(hFrame, SW_SHOWNORMAL);
    UpdateWindow(hFrame);

    MSG msg;

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

    return (int)msg.wParam;
}

from wxwidgets.

vadz avatar vadz commented on June 3, 2024

Yes, the native control ignores the provided height but wx tries to work around this, see wxChoice::MSWUpdateVisibleHeight(). And this code doesn't seem DPI-aware :-(

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

Actually, height of combobox can be changed, using CB_SETITEMHEIGHT.

However, calling ComboBox_SetItemHeight(hComboBox, -1, ctlHeight); results in the combobox a bit taller than the edit. It is because CB_SETITEMHEIGHT sets the height only of the item selection rect inside the control, so the actual control is a bit taller.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024
aaaa ICON "huo.ico"
s1 PNG
"s1.png"
s2 PNG
"s2.png"
//aaaa ICON "wx/msw/std.ico"

#define wxUSE_NO_MANIFEST         0
#define wxUSE_DPI_AWARE_MANIFEST  0

#include "wx/msw/wx.rc"

A very old interface will be displayed. Although the text is very blurry, the style is normal.
微信截图_20240407204948

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

Yes, the native control ignores the provided height but wx tries to work around this, see wxChoice::MSWUpdateVisibleHeight(). And this code doesn't seem DPI-aware :-(

@vadz, if a wxChoice is created with a large enough non-default size, m_heightOwn is -1 and so when wxChoice::MSWUpdateVisibleHeight() is called, the item height is not set. I don't think it is DPI-related.

The height is accepted if the size is set after creating the control:
wx-choice-height-workaround

@mojie126, I think I found a workaround. Create the control with a height one pixel smaller and set the requested size only after it is created.
For example, add CallAfter() at the end of the frame/dialog constructor (after wxSmith-generated code) and set sizes in the function from there.

E.g., something like

 const int ctlHeight = FromDIP(50);
...
 m_choice = new wxChoice(panel, wxID_ANY, wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight - 1));
...
// end of the ctor
 CallAfter([this, height = ctlHeight]
     {
         m_choice->SetSize(wxSize(-1, height));
     });

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

Yes, the native control ignores the provided height but wx tries to work around this, see wxChoice::MSWUpdateVisibleHeight(). And this code doesn't seem DPI-aware :-(

@vadz, if a wxChoice is created with a large enough non-default size, m_heightOwn is -1 and so when wxChoice::MSWUpdateVisibleHeight()` is called, the item height is not set. I don't think it is DPI-related.

The height is accepted if the size is set after creating the control: wx-choice-height-workaround

@mojie126, I think I found a workaround. Create the control with a default size and set the size only after it is created. For example, add CallAfter() at the end of the frame/dialog constructor (after wxSmith-generated code) and set sizes in the function from there.

DWORD screen = 0;

void SuperBDXDialog::OnScreenChanged(wxMoveEvent &event) {
	std::vector<MONITORINFO> monitor_list;
	EnumDisplayMonitors(nullptr, nullptr, EnumMonitor, (LPARAM) &monitor_list);
	for (const auto &x: monitor_list) {
		//移动到其他屏幕
		if (x.dwFlags != screen) {
			OnUpdateUIFromDIP();
			screen = x.dwFlags;
		}
	}
}

I monitored the movement of the window. When it is opened for the first time, it will look like the previous picture. After the movement, the height of the control will be restored, but the text will still be attached to the upper edge.
微信截图_20240407211926

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024
	CallAfter(
		[&] {
			DIPwxSize(Choice1, 115, 25, 58, 320);
		}
	);

Add the above code at the end of the constructor. Indeed, the height of the control is normal when it is opened for the first time, but the text is still attached to the upper edge instead of being horizontally centered.
微信截图_20240407213556

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

but the text will still be attached to the upper edge.

But that is the correct native look: The text in the combo box and edit controls is always is top-aligned, is it not? It appears odd in your screenshot because the controls there are too tall for a single-line text. There probably is a reason why combobox sticks to its height and ignores the attempts to change it...

If you create a very tall wxChoice and run it as only System DPI Aware or even DPI unaware, is the text vertically centered there? It certainly is not for me.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024
void SuperBDXDialog::OnUpdateUIFromDIP() {
	CallAfter(
		[&] {
			this->SetWindowVariant(wxWINDOW_VARIANT_NORMAL);
			this->SetClientSize(wxSize(this->FromDIP(800), this->FromDIP(600)));
			this->SetClientSize(this->FromDIP(-1), this->FromDIP(-1));
			DIPwxSize(StaticBox1, 784, 280, 8, 8);
			DIPwxSize(StaticBox2, 784, 144, 8, 296);
			DIPwxSize(StaticBox3, 784, 58, 8, 448);
			DIPwxSize(StaticBox4, 784, 58, 8, 520);
			......
		}
	);
}

My current high DPI adaptation function is like this. There is no problem with the control style, but the text in wxTextCtrl and wxChoice is not normal.

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

@mojie126, you may have missed my previous post: #24459 (comment)

To conclude: IMO, there is no issue with DPI scaling here. The only issue is that wxChoice may ignore the custom height when created, but that is unrelated.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

@mojie126, you may have missed my previous post: #24459 (comment)

To conclude: IMO, there is no issue with DPI scaling here. The only issue is that wxChoice may ignore the custom height when created, but that is unrelated.

Yes, but this size is normal at 100% DPI, including the text part

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

Yes, but this size is normal at 100% DPI, including the text part

Did you really read the post I referenced, which IMO explains it?

Is your answer to the question there Yes (i.e., is text in a very tall wxChoice at 100%DPI or when DPI-unaware really vertically aligned for you) and can you provide the screenshot and short, self-contained code (best one of the mine modified)? I tried with wxWidgets as well directly with the native control: The text is always top-left aligned within the combobox item rect. This has nothing to do with DPI.

Sorry, but your code is horrible, so many hard-coded literals and workarounds for something that normally works out of the box... I am not saying that using sizers is always perfect and painless, but in general, one is MUCH better off using them than not (just like with seatbelts).

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

I took your advice seriously IMO, the "yes" I answered was that my sizes are fine at 100% DPI, I haven't tried other sizes

The main reason is that I can no longer transform this project to use Sizer layout, so I can only try to correct this style problem under the existing conditions.

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

I took your advice seriously IMO, the "yes" I answered was that my sizes are fine at 100% DPI,

I did not ask about sizes. I literally asked: "If you create a very tall wxChoice and run it as only System DPI Aware or even DPI unaware, is the text vertically centered there?" You can try that at any DPI, all that matters is that the control is much taller than it needs to be, so you can tell how the text is vertically aligned.

Once again, I believe your problem is that you create wxChoice too tall which makes its top alignment of text noticeable. The correct size makes it look as if the text was vertically aligned, even when it really is not, since there are no extra pixels to make it obvious.

EDIT As I wrote earlier, you could try something like m_choice->SetSize(-1, m_choice->GetSizeFromText("ABC").y); instead of using a hard-coded number.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

"If you create a very tall wxChoice and run it as only System DPI Aware or even DPI unaware, is the text vertically centered there?"

There is really no way to vertically center this problem, but I want to keep the visual consistency between other DPI and 100% DPI, so I want to try to make the style of the control consistent with the text under 200% DPI.

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

There is really no way to vertically center this problem, but I want to keep the visual consistency between other DPI and 100% DPI, so I want to try to make the style of the control consistent with the text under 200% DPI.

Sorry, this does not answer my question (Yes or No) and the text makes no sense to me, English is not my first (nor second nor third) language. AFAICT, this whole issue has nothing to do with a control style anyway and it is about control appearance and I think that I said all I could and believe there is no real issue in wxWidgets.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

English is not my first language. I am using Google Translate. Maybe I did not understand your question thoroughly enough and my answer was not very correct. I now know that this is not a problem with wxWidgets.

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

There is really no way to vertically center this problem, but I want to keep the visual consistency between other DPI and 100% DPI, so I want to try to make the style of the control consistent with the text under 200% DPI.

Sorry, this does not answer my question (Yes or No) and the text makes no sense to me, English is not my first (nor second nor third) language. AFAICT, this whole issue has nothing to do with a control style anyway and it is about control appearance and I think that I said all I could and believe there is no real issue in wxWidgets.

Anyway, thank you for your guidance. At least I have solved the problem of the height of the control under high DPI. Thank you.

from wxwidgets.

oneeyeman1 avatar oneeyeman1 commented on June 3, 2024

@mojie126 ,
As suggested by PB, you should convert you project to use sizers. Than everything will be consistent as much as possible.

There are many tutorials about them on the web and the documentation is pretty good.

Moreover, there are multiple RAD tools available to help design the GUI.

Thank you.

from wxwidgets.

PBfordev avatar PBfordev commented on June 3, 2024

For the last time, the "issue" here is that your code sets the wxChoice height too big, which exposes its actual vertical text alignment being top, not center. This is normally not seen when the control is created at its optimum height.

So, if you want to get rid of the "misalignment" and refuse to use sizers, I would try to:

  1. Size wxChoices at their optimal height, where their text appears to be vertically centered.
  2. Use that height for the other controls where you want their height to be the same as wxChoice (e.g, wxTextCtrl).

For example, something like this

#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
    MyFrame(wxWindow* parent = nullptr) : wxFrame(parent, wxID_ANY, "Test")
    {
        wxPanel* panel = new wxPanel(this);

        int ctlHeight = FromDIP(25);
        const int ctlWidth = FromDIP(50);
        const int ctlY = FromDIP(5);
        int ctlX = FromDIP(5);

        m_textCtrl1 = new wxTextCtrl(panel, wxID_ANY, "text ctrl", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        ctlX += ctlWidth + FromDIP(5);
        m_choice = new wxChoice(panel, wxID_ANY, wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));
        m_choice->AppendString("ABC"); m_choice->Select(0);

        ctlX += ctlWidth + FromDIP(5);
        m_textCtrl2 = new wxTextCtrl(panel, wxID_ANY, "text ctrl", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        AdjustTextControlHeights();

        Bind(wxEVT_DPI_CHANGED, [this](wxDPIChangedEvent& e)
            {
                e.Skip(); AdjustTextControlHeights();
            });
    }
private:
    wxChoice* m_choice;
    wxTextCtrl* m_textCtrl1;
    wxTextCtrl* m_textCtrl2;

    void AdjustTextControlHeights()
    {
        const int ctlHeight = m_choice->GetSizeFromText("Äg").y;

        m_textCtrl1->SetSize(wxSize(-1, ctlHeight));
        m_choice->SetSize(wxSize(-1, ctlHeight));
        m_textCtrl2->SetSize(wxSize(-1, ctlHeight));
    }
};

class MyApp : public wxApp
{
    bool OnInit() override
    {
        (new MyFrame)->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

In a real code, you may need to use the text control height to adjust vertical position of some other controls (e.g., static texts, buttons, and check boxes) on the same row, so that all the controls on the same row appear vertically centered.

from wxwidgets.

vadz avatar vadz commented on June 3, 2024

Just one small addition: to use default height (of any control, not just wxChoice), you can specify the vertical component as -1 (a.k.a. wxDefaultCoord).

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

@mojie126 , As suggested by PB, you should convert you project to use sizers. Than everything will be consistent as much as possible.

There are many tutorials about them on the web and the documentation is pretty good.

Moreover, there are multiple RAD tools available to help design the GUI.

Thank you.

Thanks for your advice

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

For the last time, the "issue" here is that your code sets the wxChoice height too big, which exposes its actual vertical text alignment being top, not center. This is normally not seen when the control is created at its optimum height.

So, if you want to get rid of the "misalignment" and refuse to use sizers, I would try to:

  1. Size wxChoices at their optimal height, where their text appears to be vertically centered.
  2. Use that height for the other controls where you want their height to be the same as wxChoice (e.g, wxTextCtrl).

For example, something like this

#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
    MyFrame(wxWindow* parent = nullptr) : wxFrame(parent, wxID_ANY, "Test")
    {
        wxPanel* panel = new wxPanel(this);

        int ctlHeight = FromDIP(25);
        const int ctlWidth = FromDIP(50);
        const int ctlY = FromDIP(5);
        int ctlX = FromDIP(5);

        m_textCtrl1 = new wxTextCtrl(panel, wxID_ANY, "text ctrl", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        ctlX += ctlWidth + FromDIP(5);
        m_choice = new wxChoice(panel, wxID_ANY, wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));
        m_choice->AppendString("ABC"); m_choice->Select(0);

        ctlX += ctlWidth + FromDIP(5);
        m_textCtrl2 = new wxTextCtrl(panel, wxID_ANY, "text ctrl", wxPoint(ctlX, ctlY), wxSize(ctlWidth, ctlHeight));

        AdjustTextControlHeights();

        Bind(wxEVT_DPI_CHANGED, [this](wxDPIChangedEvent& e)
            {
                e.Skip(); AdjustTextControlHeights();
            });
    }
private:
    wxChoice* m_choice;
    wxTextCtrl* m_textCtrl1;
    wxTextCtrl* m_textCtrl2;

    void AdjustTextControlHeights()
    {
        const int ctlHeight = m_choice->GetSizeFromText("Äg").y;

        m_textCtrl1->SetSize(wxSize(-1, ctlHeight));
        m_choice->SetSize(wxSize(-1, ctlHeight));
        m_textCtrl2->SetSize(wxSize(-1, ctlHeight));
    }
};

class MyApp : public wxApp
{
    bool OnInit() override
    {
        (new MyFrame)->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

In a real code, you may need to use the text control height to adjust vertical position of some other controls (e.g., static texts, buttons, and check boxes) on the same row, so that all the controls on the same row appear vertically centered.

It’s not that I don’t want to use Sizer layout, it’s just that the amount of work involved in this transformation is too great. I have adopted your suggestion to control the height of the control.

from wxwidgets.

vadz avatar vadz commented on June 3, 2024

@mojie126, you may have missed my previous post: #24459 (comment)

To conclude: IMO, there is no issue with DPI scaling here. The only issue is that wxChoice may ignore the custom height when created, but that is unrelated.

So should this be closed or left open with a different title? It might be better to create a different issue for the custom height problem to make things less confusing...

from wxwidgets.

mojie126 avatar mojie126 commented on June 3, 2024

It really should be closed, but I hope the official can provide a solution that can set the item

from wxwidgets.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.