Winapi c++ make static image behave like a button (Hover, Click) - c++

I want to change a Static bitmap image when hovering it. I've tried using a button instead, but the picture never fill the button. I've tried too TrackMouseEvent but I want it to be always active so i cannot use this. Is there a way to get notified when mouse hover a static control or to make a control that behaves like that?
This is my control:
HWND Button = CreateWindow("Static", NULL,
WS_VISIBLE | WS_CHILD | SS_BITMAP | SS_NOTIFY,
20, 240, 120, 20,
hwnd, (HMENU)101, NULL, NULL);
SendMessage(hwnd, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)view.vBitMap);
I use SS_NOTIFY nto get notified when user clicks it or doubleclicks it, but unlike BS_NOTIFY, it don't tell when hovering on WM_NOTIFY

Related

Static text with scrollbar win32

Hi guys I'm trying to make static text with a scrollbar. I created a scrollbar window with editable text this way:
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", text, WS_CHILD | WS_VISIBLE | WS_VSCROLL| ES_AUTOVSCROLL, posX, posY, width, height, parWindow, HMENU(ID), hinstance, NULL);
and it is working properly, but when I do the same thing and change the "EDIT" to "STATIC", the scrollbar stop working. Any ideas without using WM_SCROLL message?
As far as I am aware the static control does not honor scroll messages (I checked the wine sources and the static control file does not have the string "scroll" anywhere), you will have to implement this yourself.
Note that instead of a static control, you might want to consider a read-only edit control. You could still get edit's scroll handling that way.

Win32 Button doesn't properly display in a Direct2D Window

I have a Direct2D program, and my goal is to have a Win32 button rendered with the Direct2D window.
I was able to compile the program fine, but the problem is that the button only shows when I click on it. Once I click outside of the button, it just goes invisible. It's even invisible when I open the application. What I expect is for the button to be visible all the time. I'm not necessarily worried about if it renders above or below the Direct2D renderer.
When I click on it:
When I click outside the button (just blank):
Here is my render function:
create_drs(); // Creates device resources
m_pRenderTarget->BeginDraw();
m_pRenderTarget->Clear(D2D1::ColorF(bg.r / 255, bg.g / 255, bg.b / 255, 1));
HWND hwndButton = CreateWindow(
L"BUTTON",
L"a button",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
0,
0,
150,
150,
m_hwnd,
NULL,
(HINSTANCE)GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE),
NULL);
m_pRenderTarget->EndDraw();
I've tried taking out the Clear function, but it's still invisible when the application opens, but stays visible forever once I click on it. I also tried looking online, but couldn't find a sufficient solution for this specific problem.

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);

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.

List Control SetFocus Redraw Error on a Tab Control

Environment: Visual Studio 2008, Visual Studio Feature Pack, MFC Dialog App, Windows XP, New Common Controls.
I'm having a problem with a list control that happens to be on a tab control.
To reproduce the problem simply create a dialog based app. Place a tab control on that dialog, then put a list control onto that tab control. You don't need to add any code to the project. Just build and run. Set the focus to the list view and then either minimize the dialog or bring another window in front of it.
Now bring the dialog back to the foreground, the list will not draw itself correctly.
One thing I have tried is handle the set focus event for the list control, but left it with an empty method body, ie...
void CMyListControl::OnSetFocus(CWnd* window)
{
// Default();
}
Then the redraw problem goes away, however now you can not select items within the list. Uncommenting the call to Default makes the problem come back.
If I move the list off of the tab the problem goes away. If I set the focus to another control on the tab or dialog, the problem goes away. This is a weird one.
In fact, if you watch closely you can see the list drawing itself and then being obscured by the tab control.
I know it's late but I had them same problem today. You need to set ListView's parent to Tab control.
hWndTab = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TABCONTROL, NULL,
WS_CHILD | WS_TABSTOP | WS_VISIBLE,
0, 0, 0, 0, hWnd, (HMENU) IDC_TAB, hInstance, NULL);
hWndList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL,
WS_CHILD | WS_TABSTOP | WS_VISIBLE | LVS_REPORT,
0, 0, 0, 0, hWndTab, (HMENU) IDC_LIST, hInstance, NULL);
Note parent window handler for hWndList: hWndTab. Or you can use SetParent.