How to make edit controls have 3D look? - c++

I created an edit control by the following code:
hWnd = CreateWindowExW( 0, // extended styles
L"EDIT",
L"Text in edit.",
ES_LEFT | WS_VISIBLE | WS_CHILD,
10, // x
50, // y
30, // width
100, // height
hWndMainWindow,
NULL,
hInstance,
NULL);
My edit control looks like this:
But most edit controls I see in Windows have a 3D look like in the image below:
I tried several extended and normal window styles, but the didn't do any good. How do I make my edit control look like in the second image?
Some quick links that may help you to take reference:
Window Styles
Extended Window Styles
Edit Styles

You need to include the WS_EX_CLIENTEDGE extended window style.
You say that you have already tried including WS_EX_CLIENTEDGE without success. I'm going to take a wild guess that you have been trying to include it in the window style rather than the extended window style. Your code should look like this:
hWnd = CreateWindowExW(
WS_EX_CLIENTEDGE, // extended styles
L"EDIT",
...
);

Related

Draw Resource Icon on Button

I would like to draw my program's icon on an "owner-drawn" button. This could be either an icon in the resource file, or the generic Windows icon. But, even after endless searching, I have not been able to find the code for this. I have come across bits and pieces of answers. But, no complete explanations.
Sorry that I have no code to post. I am totally lost on this one. Either standard Win API or GDI+ will work for me.
When you create the button, add BS_ICON style, then get the handle to your icon, you can use LoadImage.
Finally send BM_SETIMAGE message with the handle to your icon.
Here is the code sample:
HWND button1 = CreateWindow(TEXT("Button"), TEXT("OK"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_ICON,
50, 50, 50, 50, hwnd, (HMENU)1001, hInstance, NULL);
HICON hIcon = (HICON)LoadImage( // returns a HANDLE so we have to cast to HICON
NULL, // hInstance must be NULL when loading from a file
L"iconname.ico", // the icon file name
IMAGE_ICON, // specifies that the file is an icon
0, // width of the image (we'll specify default later on)
0, // height of the image
LR_LOADFROMFILE | // we want to load a file (as opposed to a resource)
LR_DEFAULTSIZE | // default metrics based on the type (IMAGE_ICON, 32x32)
LR_SHARED // let the system release the handle when it's no longer used
);
SendMessage(button1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);

Win32 semi transparent window

I'm trying to get a semi transparent window with the Win32 API and C++. Despite the fact, that there
are around a million results trying to answer that question, none of those seem to have worked for my case.
I have a native Win32 window with a hosted WPF content inside it. Because I'm trying to create a custom
window frame (and that also works by now), I want the top part of the self drawn frame to be semi
transparent, possibly also applying the acrylic blur.
Looking at WPF, I could archive my goal using AllowTransparency = True on the window and with a
transparent background. Now I need a way to replicate that behavior with the Win32 API.
Technically, I can make the entire main window transparent (because the main window is the frame entirely
and the WPF hosted content is the client area), but even that didn't work (no transparency).
For reference, here is how I'm creating my window:
WNDCLASSEXW window_class_ex = {
sizeof(WNDCLASSEXW),
CS_HREDRAW | CS_VREDRAW,
window_callback,
0,
0,
application_instance,
nullptr,
LoadCursorW(nullptr, IDC_ARROW),
CreateSolidBrush(RGB(0, 0, 0)),
nullptr,
window_class,
nullptr
};
const HWND window_handle = CreateWindowExW(
0,
window_class,
L"WinSoup",
WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_EX_LAYERED,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
nullptr,
nullptr,
application_instance,
reinterpret_cast<LPVOID>(owner)
);
I have seen that I should use WS_EX_LAYERED, but also that didn't have the desired effect.
Of course the WPF content itself should not be transparent!
Ok, so, despite all the answers telling me to read the documentation and look at other
examples... turns out, I misplaced the WS_EX_LAYERED.
const HWND window_handle = CreateWindowExW(
WS_EX_LAYERED, // Needs to be placed here (extended style)
window_class,
L"WinSoup",
WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, // Not here!
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
nullptr,
nullptr,
application_instance,
reinterpret_cast<LPVOID>(owner)
);
Your question says
The WPF content itself should not be transparent!
You can use Set/UpdateLayeredWindowAttributes, but the opacity for your WPF content will change too.
If you really want to create a high-performance transparent/semi-transparent window, you need to specify the WS_EX_NOREDIRECTIONBITMAP flag instead of WS_EX_LAYERED. Then use DirectComposition with another graphics API to render your content.
Look at https://msdn.microsoft.com/magazine/dn745861.aspx for more details.

How to make Win32 EDIT window on desktop outside of dialog take up all space

I need to create an EDIT control directly on the desktop without being inside of a dialog box. I need the text box to take up all the available space in the window.
Currently I am trying to just do something like:
CreateWindow(L"EDIT", nullptr, WS_VISIBLE, 0, 0, 300, 50, nullptr, nullptr, nullptr, nullptr);
But that results in a textbar that's almost as wide as my window, but not nearly as tall, surrounded by a transparent background.
I'm relatively new to win32 programming so any pointers in the right direction would be helpful.
Looks like I just needed to add WS_POPUP in addition to WS_VISIBLE

WINAPI Button background

In WINAPI, I create a button like:
case WM_CREATE:
{
Start = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
break;
}
The button looks like:
But I need it to look like this one (which I did in .Net):
How can I get rid of that black border/background?
Start = CreateWindowEx(WS_EX_TRANSPARENT, ...);
You got the black outline because you used the WS_EX_TRANSPARENT style flag. It isn't clear why you used it, there's not much you can do with it when you use the Button control. It is otherwise probably the least understood style flag. Pass 0 instead to get a normal looking button.
It is otherwise a lost cause to get the exact look of a .NET button, Winforms doesn't use the built-in Button control. It creates its own, using a custom renderer to get the gradient look. Reproducing that native code is a lot of work.
I think the border you are seeing is because the button has the "Default Button" property. If you turn that off, then it will have a normal border. The Default property just tells Win32 which button to activate if the users hits ENTER on the dialog/form. If you only have one button, then it will always have the default property. If you add a second, it will not.
The property is the BS_DEFPUSHBUTTON property, so in your CreateWindowEx call, you should be able to do something like:
Start = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | ~BS_DEFPUSHBUTTON, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
If not, you'll have to set it with ModifyStyle or ModifyStyleEx, and pass it in the "Remove" parameter. I forget which one the specific styles have to be passed in, but if I recall correctly, it's the normal style params, NOT the EX params.
I haven't tested this, but try creating the button like this:
Start = CreateWindowEx(0, WC_BUTTON, "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
break;
It also might depend on how you've created your main window. Can you post the code for your main window creation?
EDIT: I mis-identified the border as the default-button border. As David Hefferman pointed out, it's not. That is, I have now reproduced that border effect; when the program starts there is no border, but just a little mousing over the left button creates the border – at least in Windows 7.
Original answer follows:
The black border is because it's default. You shouldn't interfere with the system's visualization of default buttons etc. Users rely on those cues.
To change the font, maybe, like, WM_SETFONT?
Disclaimer: I haven't tried that. It might be you need to handle WM_CTRLCOLOR or something like that. Just try it out, and in the end, if the default buttons don't cut it for you, simply implement your own button.

Groupbox Font Issue with WinAPI

I have problems with creating a simple Group-Box-Control via CreateWindowEx. The font-size/-style of its caption just doesn’t look right.
I have created a simple Windows Dialog (containing group-boxes, buttons…) with the Visual Studio - Resource Manager. When I load that dialog with DialogBox(…) everything looks normal but when I create another group-box-control on that same dialog via CreateWindowEx(…) the caption of the new control has a different font-size/-style.
With Microsoft Spy++ I was able to see the dwExStyle and dwStyle values of the other groub-boxes, but even when I use the same values in CreateWindowEx I still get a different look.
Here is the code I use to create the new group-box:
HWND hGroup1 = GetDlgItem(_hWnd, IDC_GROUPBOX1);
HWND hGroup2 = CreateWindowEx(
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOPARENTNOTIFY,
L"Button",
L"Hallo",
WS_CHILDWINDOW | WS_VISIBLE | BS_GROUPBOX,
20, 20, 250, 250,
hGroup1,
nullptr,
_hInstance,
nullptr);
Here is a screen capture of the dialog:
http://imageshack.us/photo/my-images/856/groupboxfontissue.png/
Please let me know where I went wrong and what I can do to fix it.
[EDIT-1]
In regards to Jonathan Potter and Superman, as you suggested I set the font-handle of the new group-box to the same as for the other controls.
HFONT hFont1 = (HFONT)SendMessage(hGroup1, WM_GETFONT, 0, 0);
HFONT hFont2 = (HFONT)SendMessage(hGroup2, WM_GETFONT, 0, 0);
HFONT hFont3 = (HFONT)SendMessage(_hWnd, WM_GETFONT, 0, 0);
SendMessage(hGroup2, WM_SETFONT, (WPARAM)hFont1, TRUE);
hFont2 = (HFONT)SendMessage(hGroup2, WM_GETFONT, 0, 0);
At the end of this code, I can see that all controls and the dialog window have the same font-handle but only the controls which were created with the Resource Manager have the correct font (which is the system font).
Is there anything else I can do???
[EDIT-2]
I cannot believe it… it works now! Thank you all very much for your help!
I just had to set the hWndParent value in CreateWindowEx(…) to the dialog handle and then use WM_GETFONT and WM_SETFONT to copy the right font.
I wish you all a nice weekend.
Controls you create manually (via CreateWindowEx) do not get their font set automatically, and will default to the "system font" (which is what you see in your screenshot). Instead, you need to set the control's font once it has been created. For example,
SendMessage(hGroup2, WM_SETFONT, (WPARAM)SendMessage(hGroup1, WM_GETFONT, 0, 0), TRUE);
When you place a control in a dialog using the resource editor, the font set to the dialog, which is the parent of the control will be used for it by default.
If you're creating a control dynamically, the system font will be used instead of the font of the dialog.
To get the same font of the dialog for a control that you create dynamically, set the font of the dialog to the control in the WM_INITDIALOG handler.
In the code snippet below, replace m_hWnd with the handle of the parent dialog.
HFONT font = (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
::SendMessage(hGroup2, WM_SETFONT, (WPARAM)font, TRUE);