Visual style set on BS_CHECKBOX button overrides NM_CUSTOMDRAW - c++

I am looking to create a checkbox in the C++ WinAPI with a custom bitmap resource as the actual check box.
Unfortunately, when I create a WM_NOTIFY-compatible checkbox (That actually deals with NM_CUSTOMDRAW in a meaningful way), it seems to work just fine except for one thing: The checkbox seems to fade when changing states. This has to do with the visual style, it seems, so I simply unset the visual style with SetWindowTheme(chkLogging, _T(" "), _T(" "));.
HWND chkLogging = CreateWindowEx(
NULL,
_T("button"),
_T("Export to log file"),
WS_VISIBLE | WS_CHILD | BS_CHECKBOX | BS_NOTIFY,
300, 100, 100, 20,
hWnd, (HMENU)IDC_EXPORTLOG, NULL, NULL);
CheckDlgButton(hWnd, IDC_EXPORTLOG, BST_CHECKED);
SetWindowTheme(chkLogging, _T(" "), _T(" "));
Unfortunately, setting the theme for that HWND will override the NM_CUSTOMDRAW rendering. I have tested this by removing the SetWindowTheme line and trying with the default theme, and the checkbox NM_CUSTOMDRAW worked like a charm.
This typically wouldn't be an issue, but it actually works as seemingly intended for normal buttons.
Any assistance on this matter would be greatly appreciated :)

Related

How to make tab key work in C++ Win32 API

I am a noob for C++ Win32 API. I am trying to make a textbox (edit control). In the textbox, I want to make the tab key act as it would in notepad, i.e., it would advance the cursor to the next tab stop in a textbox. I made a simple edit control with some scrollbars, auto-scrolling and multiline styles. I want the tab key to advance the cursor to the next tab stop. But it doesn't happen. The tab key doesn't do anything, literally nothing. It acts as if it wasn't assigned to do any task inside an edit control.
If anyone knows how to do that, I would be really grateful to him.
Here's the full code which I used for creating an edit control :-
HWND hTb = CreateWindow
(
L"Edit", L"LOL",
WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL | ES_WANTRETURN | WS_TABSTOP,
0, 0, LOWORD (lp), HIWORD (lp),
hWnd, NULL, NULL, NULL
);
I am creating hTb in the WM_CREATE message of the WndProc. This edit control is just used for resizing it and nothing complicated. Here's the code :-
case WM_SIZE :
{
MoveWindow (hTb, 0, 0, LOWORD (lp), HIWORD (lp), TRUE);
break;
}
Thanks in advance.
Edit controls will not receive tabs if "the dialog manager" portion of Win32 is engaged. For a modeless dialog box, the way you will see dialog box semantics showing up in a window is if the application's main message loop is filtering messages with the API call IsDialogMessage. IsDialogMessage will reroute tab presses to the window rather than the focused control, in this case the edit box.
To fix the problem use a standard message loop. That is,
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
not
while(GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
You can read more about the dialog manager on Raymond Chen's blog: here, here, and here

How to update the current state for window after showing/hiding controls?

I'm a beginner and today is my first day in learning to create Windows application.
I have two buttons.
#define BUTTON_SW 1
#define BUTTON_SW2 2
HWND Button1;
HWND Button2;
Button1 = CreateWindow("button", "Enter", WS_VISIBLE | WS_CHILD, 215, 10, 40, 25, hwnd, HMENU(BUTTON_SW), NULL, NULL);
Button2 = CreateWindow("button", "You'll be gone", WS_VISIBLE | WS_CHILD, 260, 10, 95, 25, hwnd, HMENU(BUTTON_SW2), NULL, NULL);
When Button1 is clicked, how can I hide Button2 or make it lose its WS_VISIBLE flag and reflect current situation correctly, like this?
LONG style = GetWindowLong(Button2,GWL_STYLE);
style = style | WS_VISIBLE; // style = style & ~WS_VISIBLE
SetWindowLong(Button2,GWL_STYLE,style);
This works very well. However, once WS_VISIBLE flag is assigned, button still stays invisible until the first mouseclick on it.
Vice versa, when I use style = style & ~WS_VISIBLE; once WS_VISIBLE flag is removed, button becomes passive (unclickable) but stays visible.
How to fix this? Tried many things that I've found online but couldn't fix it. Also please don't suggest me to buy a decent book, I don't have the money for now.
(P.S: ShowWindow function with SW_HIDE/SW_SHOW somehow doesn't work for me, perhaps I'm using it wrong. Can you help me on how I can hide this Button2 correctly? I'm trying the following command, but nothing happens.)
ShowWindow(GetDlgItem(Button2, 2), SW_HIDE);
#Edit: I've noticed that when I minimize the app and maximize it
again, the state of button updates. But how will it automatically
update the state?
This should work
ShowWindow(Button2, SW_HIDE);
or
ShowWindow(GetDlgItem(DialogHWND, BUTTON_SW2), SW_HIDE);
GetDlgItem needs HWND of the parent window (dialog) as first argument.
In order to a window to reflect changes you must ask the OS to do it.
Learn about RedrawWindow and the invalidated area.
Note that some actions, like resizing or restoring from minimized, automatically makes the OS to invalidate the region and redraw it.
Use:
RedrawWindow(Button2,NULL,NULL,RDW_INVALIDATE | RDW_INTERNALPAINT);

Multiline button in winapi

How can I create a multiline button in winAPI (\n or even \r\n doesn't work). Here is the code:
HWND hPrzyciskoff = CreateWindowEx( 0, "BUTTON", "Play offline", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 410, 550, 380, 25, hwnd, NULL, hInstance, NULL );
Add BS_MULTILINE to the styles you specify in the 4th argument of CreateWindowEx().
As the documentation of Button Styles explains:
BS_MULTILINE
Wraps the button text to multiple lines if the text string is too long to fit on a single line in the button rectangle.
The \n characters inside the button text will then have the desired effect.
Check the screenshot on the Button Types page to see how it looks like.
Alternative to a big multiline push button could be a command link button BS_COMMANDLINK. It has a main text and extra notes (setup via BCM_SETNOTE message or Button_SetNote macro), shown in different size fonts. The fonts are predefined and cannot be changed as far as I know. There is also a default green arrow, which can be replaced with another image (via BM_SETIMAGE), but cannot be removed entirely. However, the button background can be changed via WM_CTLCOLORBTN message (this does not work for any other pushbutton), which can be quite handy sometimes, e.g. to blend with the window background like in toolbar.

How to create win7 style button using CreateWindowEx [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
winapi CreateWindowEx -> create button with user system styles?
Hi,
I am kinda new to WinAPI and C++ and I am using Visual Studio 2010. I want to create some buttons in the main window. So there are two questions:
1) can I use a dialog window created with resource editor as a main window so that I wouldnt have to create all controls "by hand" in the "post-WM_CREATE message" section?
2) (If I cant use resource script made window with buttons as a main window) When I "hand make" button using CreateWindowEx like this:
case WM_CREATE:
{
HFONT buttonFont = CreateFont(-11, 0, 0, 0, 400, FALSE, FALSE, FALSE, 1, 400, 0, 0, 0, fontButtonFont);
HWND bMainOK = CreateWindowEx(
0,
WC_BUTTON,
szOkButton,
WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON,
24, 200, 75, 23,
hWnd,
0,
hInst,
0);
SendMessage(bMainOK, WM_SETFONT, (WPARAM)buttonFont, FALSE);
}
I get very ugly oldstyle button. How do I make it look like Win7/Vista button? Or better how do I make it behave as system style setting says (when using XP get XP style button, when using Vista get Vista style button etc.)?
Thanks
You need to link a manifest to your app that specifies v6 common controls. Websearch will do the rest for you.

Changing a dialog's style at creation to override what's in the .RC template

I have a little dialog I created using Resource Editor in VS2005. It's going to be used as a child dialog of another dialog, in 2 different ways... either as a child which sits on top of the dialog like a custom control, or as a popup which can move beyond the boundaries of the parent window. If I modify a single style in the RC file, both of these work as expected - simply substitute WS_POPUP for WS_CHILD to toggle:
IDD_WIDGET DIALOGEX 0, 0, 221, 78
STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_POPUP | WS_BORDER
EXSTYLE WS_EX_TOOLWINDOW | WS_EX_STATICEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Pre&view",IDC_ACTION_PREVIEW,64,59,50,15
PUSHBUTTON "M&ore",IDC_ACTION_MORE,115,59,50,15
PUSHBUTTON "S&elect",IDC_ACTION_SELECT,168,59,50,15
END
The problem is, I want to be able to choose the behavior when creating the child dialog at run-time as a sort of widget type framework, e.g overriding the RC file style
I tried:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_Widget.Create(IDD_WIDGET,this);
DWORD oldstyle = m_Widget.GetStyle();
m_Widget.ModifyStyle(WS_POPUP,WS_CHILD);
DWORD newstyle = m_Widget.GetStyle();
}
But it makes no difference that I can see, other than that the result of GetStyle changes from 0x8400044C to 0x4400044C... the widget child-dialog starts invisible but when I show it, it retains the WS_POPUP behavior.
What's wrong, and how can it be fixed?
As Ben suggests, I wonder if this is not a style that can be changed after the window is created, but the problem then is how to intercept the dialog-template structure and modify the style before it's used to create the window?
I found this article for you: link text
Looks like InitDialog is too late to change the style. There's an example of how to do it in this link.