KeyWorksRW / wxUiEditor

RAD tool used to create and maintain wxWidgets UI elements.
Apache License 2.0
62 stars 5 forks source link

Bug: For a wxCalendarCtrl widget the font property is not available #1472

Open rossanoparis opened 1 month ago

rossanoparis commented 1 month ago

Description:

The font property is not shown for this widget. Is it intentional?

image

KeyWorksRW commented 1 month ago

There are 9 controls that hide setting the font, and there are no comments in the interface file as to why. I need to review all 9 of these, and now that comments can be added without their being added to the executable file, each one that remains should be commented as to why.

KeyWorksRW commented 1 month ago

I tried setting the font of a wxCalendarCtrl and stepped through the code in the debugger up to the point where it sends the WM_FONT message to the Windows control (I verified that the font was valid). It had no effect -- the font of the calendar control did not change. I tried using a variant size instead and that also failed. I tried generating it as XRC and letting the wxWidgets XRC code display it -- it still didn't change. If there's a way to get the font to change on a Windows calendar control, I don't know what it is. I have not tried this on Linux yet -- so it might work fine there.

I also tried it using wxGenericCalendarCtrl and in this case both font and variant size work just fine.

rossanoparis commented 1 month ago

Perhaps using other OSs the behaviour is different. As I see it, I'd keep the font property enabled by default for all widgets. I'd let the opportunity to use it everywhere, then it's up to the user ...

For instance, in this case I could inherit another widget from wxCalendarCtrl and follow this way to get what I need. [ from stackoverflow ]

KeyWorksRW commented 1 month ago

The link you refer to allows you to change the size, but it still doesn't allow you to change the font. I don't see the advantage of enabling an option on an OS where it clearly does not work. If it turns out that it works on Linux, then I will unhide the option, but code generation will be conditionalized to indicate that it does not work when running on Windows, and suggesting switching to the generic version which does work and provides additional capabilities as well. I really, really do not want to be generating code that doesn't work and then have to deal with the bug reports about it not working properly... 😞

KeyWorksRW commented 1 month ago

Changing the font on Linux works just fine -- and I believe the Mac version is generic, so that should work as well. The only issue I see for Linux is that the calendar control does not automatically resize to accommodate the new font size.

On Windows, calling wxCalendarCtrl::SetFont() ends up sending a WM_FONT message which Windows ignores. I believe the only way that this method would work is if Visual Styles was turned off, and that would potentially affect the appearance of all other Windows controls in your application.

I believe the correct way to set the font for a calendar control on windows is to send a DTM_SETMCFONT which wxWidgets currently does not support. I think I might be able to special-case font handling under Windows to correctly handle this by calling SendMessage(GetHandle(), DTM_SETMCFONT, ...). I'll see if I can get that working. If that works, then it gets more complicated for wxPython and wxRuby3:

wxPython:

import ctypes
from ctypes import wintypes

user32 = ctypes.WinDLL('user32', use_last_error=True)

def send_message(hwnd, msg, wparam, lparam):
    result = user32.SendMessageW(hwnd, msg, wparam, lparam)
    if not result and user32.GetLastError():
        raise ctypes.WinError(ctypes.get_last_error())
    return result

# Usage
hwnd = ...  # The handle to the window
msg = ...   # The message to send
wparam = ...  # Additional message-specific information
lparam = ...  # Additional message-specific information

send_message(hwnd, msg, wparam, lparam)

wxRuby3:

require 'win32/api'
include Win32

SendMessage = API.new('SendMessage', 'LLLP', 'L', 'user32')

hwnd = ...  # The handle to the window
msg = ...   # The message to send
wparam = ...  # Additional message-specific information
lparam = ...  # Additional message-specific information

result = SendMessage.call(hwnd, msg, wparam, lparam)
rossanoparis commented 1 month ago

Thank you @Randalphwa Thanks, it's interesting and gives me hope :)

Perhaps even the widget wxDatePickerCtrl would get benefit by the same solution. [ wxDatePickerCtrl issue ] image

Randalphwa commented 1 month ago

The following should have worked:

#include <commctrl.h>

DateTime_SetMonthCalFont(m_calendar->GetHandle(), font->GetHFONT(), true);

Unfortunately, wxWindowMSW::MSWDefWindowProc tries to process this message using m_oldWndProc (src/msw/window.cpp) and it crashes.

I do think that this could work by integrating it into wxWidgets itself. SetFont() is a virtual function, so wxCalendarCtrl should be able to override it and ultimately send DTM_SETMCFONT instead of WM_SETFONT.

I've got a lengthy PR that I'm currently working on for wxWidgets (lunasvg integration) -- once that's done, I'll see if I can get this working within wxWidgets itself. It would certainly be nice if one could just call SetFont() and have it work on all platforms rather that failing on Windows and working everywhere else.

rossanoparis commented 1 month ago

Once again thank you @Randalphwa

have it work on all platforms rather that failing on Windows and working everywhere else

I agrre with you ... it would be very welcome