Picture Control not displaying any picture - winforms

I'm currently making a dialog which holds a picture control. I set the type to BITMAP and set the image to the image I want it too. This image is also in the resource .rc file. When I set this as the bitmap for the picture control I can see it just fine in the editor, when I run my application however it does not work, I don't see anything in the picture control.
I've tried the following:
Call Initcommoncontrols(); ( this function is deprecated so I tried the InitCommonControlsEx() with the argument it wanted ) Result: Still no picture
I used the following snippet when the form is initialized:
SendMessage( GetDlgItem( aHWND, HEADERLOGO), STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap );
hBitmap is declared as:
HBITMAP hBitmap = LoadBitmap( hInstance, MAKEINTRESOURCE(BITMAP_LOGO) );
When I did getlasterror after LoadBitmap() the error code was: 1814 (0x716) which translates too ERROR_RESOURCE_NAME_NOT_FOUND
I have no clue why the image could not be found, I can see the thing just fine in the editor, get no complaints about it. hInstance is obtained from WinMain(), I also tried getting it using this snippet:
(HINSTANCE)GetWindowLong( aHWND, GWL_HINSTANCE);
I assume the WinMain HINSTANCE would be correct but just to be sure I tried this, had no effect.
After that I thought it might just be the IDE screwing up somehow so I threw away the dialog, recreated it, added new picture control, added the image again. Still same thing, looks fine in the editor but doesn't show when running the project.
I'm guessing I'm missing something really simple here, please enlighten me.

It turned out that getting the HINSTANCE inside a dialog won't work. It won't be valid to application memory. If you grab the HINSTANCE you get from WinMain it will work. My engine now grabs this one and now the HBITMAP handle is filled just fine.

Related

Why this BitBlt example doesn't work anymore?

I'm currently getting back to some Windows Programming using Petzold's book (5th edition).
I compiled the following example using BitBlt and it doesn't work as it is supposed to.
It should copy the Window's icon of (CxSource, CySource) size and replicate it on the whole window's surface.
What happens, in reality, using Windows 7 is that the bitmap below the window gets sourced and copied into the drawing surface i.e. hdcClient.
I don't understand why it behaves like this knowing that it's clear the DC passed to BitBlt is hdcWindow, which refers to a device context obtained via a GetWindowDC(hwnd) of the current application.
I first thought it was due to the fact the transparency mode is enabled by default, but deactivating it doesn't change anything. BitBlt seems to always take the surface below the application Window!
I don't get it! :)
Anyone knows why it works that way and how to fix it?
Making screenshots with BitBlt() did not exactly get any easier since the addition of the DWM (Desktop Window Manager, aka Aero). Petzold's sample code suffers from a subtle timing issue, it is making the screenshot too soon. It does so while Aero is still busy animating the frame, fading it into view. So you see what is behind the window, possibly already partly faded depending on how quickly the first WM_PAINT message is generated.
You can easily fix it by disabling the effect:
#include <windows.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
And after the CreateWindow() call:
BOOL disabled = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_TRANSITIONS_FORCEDISABLED, &disabled, sizeof(disabled));
Another tricky detail is that the first BitBlt matters, the DWM returns a cached copy afterwards that is not correctly invalidated by the animation.
This gets grittier when you need a screenshot of a window that belongs to another process. But that was already an issue before Aero, you had to wait long enough to ensure that the window was fully painted. Notable perhaps is the perf of BitBlt(), it gets bogged-down noticeably by having to do job of composing the final image from the window back-buffers. Lots of questions about that at SO, without happy answers.
It is not supposed to copy the windows icon, it is supposed to copy the windows titlebar part where the icon is located.
There are some issues with this (now 20 year old code):
GetSystemMetrics values cannot be used for window related dimensions anymore since GetSystemMetrics returns the classic sizes, not the Visual Style sizes.
Depending on the Windows version, the DWM might define the window size as something larger than your window (where it draws the window shadow and other effects).
Your example works OK on XP:
(There is a small problem because the titlebar is not square (unlike Windows 98/2000 that this example was designed for) so you see a issue in the top left where it is just white. I also modified the example slightly so it varies the HDC source location)
On a modern version of Windows it seems like the DWM or something is not able to properly emulate a simple window DC and parts of the shadow/border/effects area is part of the DC:
I don't know how to fix this but the example is pretty useless anyway, if you want to draw the window icon you should draw the HICON with DrawIconEx. If you want to draw custom non-client area stuff then you need to find more recent examples, not something that only supports the classic theme.

parts drawn with DrawThemeBackground on Windows 10 are not correct

Problem description
I want to create a Windows API app in C which renders the menu and the caption buttons in the same non-client area, similar to Firefox
In order to do this, I've determined the solution needs to:
be type WS_POPUP, in order for the menu to be aligned to the top
take ownership of the non-client area (where the menu is rendered)
manually render the minimize/maximize/close buttons
The solution needs to work on Windows 7, 8, and 10 (and ideally future versions too).
How it looks now
I have a test program available on GitHub.
In my app, I've overridden the appropriate events:
WM_NCCALCSIZE, WM_NCHITTEST, WM_NCLBUTTONDOWN, WM_NCLBUTTONUP, WM_NCMOUSEMOVE, WM_NCPAINT
And then I repaint non-client areas on these events:
WM_NCACTIVATE, WM_SETTEXT
Here's an example of how I'm doing the rendering:
// globals set elsewhere
RECT customAreaRect, minRect, maxRect, closeRect, coverMenuRect;
BOOL maximized;
// ...
LRESULT OnPaintNCA(HWND hWnd, WPARAM wParam, LPARAM lParam) {
RECT windowRect;
HRGN hRgn = NULL;
GetWindowRect(hWnd, &windowRect);
if (wParam == 1) {
hRgn = CreateRectRgnIndirect(&windowRect);
} else {
hRgn = (HRGN)wParam;
}
if (hRgn) {
// Carve out the area for custom content
HRGN captionButtonRgn = CreateRectRgnIndirect(&customAreaRect);
CombineRgn(hRgn, hRgn, captionButtonRgn, RGN_XOR);
DeleteObject(captionButtonRgn);
// Force default painting for non-client area
LRESULT ret = DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
// black background covering part of menu, behind buttons
HDC hDC = GetWindowDC(hWnd);
FillRect(hDC, &coverMenuRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
HTHEME hTheme = OpenThemeData(hWnd, TEXT("WINDOW"));
DrawThemeBackground(hTheme, hDC, WP_MINBUTTON, partState, minRect, NULL);
DrawThemeBackground(hTheme, hDC, maximized ? WP_RESTOREBUTTON : WP_MAXBUTTON, partState, maxRect, NULL);
DrawThemeBackground(hTheme, hDC, WP_CLOSEBUTTON, partState, closeRect, NULL);
CloseThemeData(hTheme);
}
}
The rendered result looks like this:
Unfortunately, the styles used for the parts (minimize, maximize/restore, close) look like the styles for Windows 7/8, and not the native Windows 10 controls. I've been searching for a way to do this for several days without luck. I need help understanding how to render these buttons for Windows 10 using the Windows API.
Current status (and what I've tried so far)
My first hunch was that I need to properly enable Visual Styles.
Per this article, calls checking the OS version will get Windows 8 unless you specifically target Windows 10 via a manifest. Click here to view my manifest. This does work:
Before GetVersionEx returned major=6, minor=2, build=9200
Now GetVersionEx returns major=10, minor=0, build=10586
Per the official "Enabling Visual Styles" article, I made sure to use Common Controls version 6.
Added linker input for Comctl32.lib
Call is made to InitCommonControls on program start
Added dependency for version 6 to the application manifest
Here are some screenshots of relevant project settings that I have tried:
Other ideas
I'm running low on things to try. Before throwing in the towel, there were some things I was going to try:
Idea 1: using GetThemeStream which allows you to retrieve the size/bitmap for controls.
Load aero msstyles file like so:
HMODULE themeFile = LoadLibraryEx(TEXT("C:\\Windows\\Resources\\Themes\\aero\\aero.msstyles"), NULL, LOAD_LIBRARY_AS_DATAFILE);
Get the bitmap for the part (minimize button, maximize button, etc) like so (passing the loaded theme file):
GetThemeStream(h, WP_MAXBUTTON, MAXBS_NORMAL, TMT_DISKSTREAM, (void**)&buffer, &bufferSize, themeFile);
Load the bitmap; it appears to be in PNG format (I haven't gotten this far)
Draw the bitmap
Idea 2: copy the non-client area from a hidden window which has the caption area (and minimize, maximize, close buttons).
Create a window which has the caption and min/max buttons, never activating it.
In the non-client paint, get the DC for that Window and capture the pixels for the min/max/close button
Render them using bitblt
I think the issue comes from trying to use WM_NCPAINT on OS version >= Win Vista.
Since Vista all NC rendering is controlled by DWM (desktop window manager). If you still dare to handle WM_NCPAINT, DWM rendering will be turned off and you get "old-school" look:
From the Shell Revealed Blog:
The DWM doesnt have any legacy worries because applications cannot
draw inside the glass frame, since its rendered and managed by a
totally different process. If an application tries to do it, Windows
will detect it and remove the glass frame entirely (and therefore
revert to the Basic frame), so that the application can draw what it
wants to draw.
To get proper results, you have to do it the "DWM way" (specifically the sections "Removing the Standard Frame" and "Drawing in the Extended Frame Window"). This works by letting DWM render the frame within the client area, so you can paint over it. Also with this solution you don't have to draw the caption buttons on your own. This answer summarizes the required steps (under "Aero supported solution").
The caveat is that you propably have to draw the menu on your own and you can't use most of GDI API for that, because GDI ignores the alpha channel and things will look ugly if the frame is translucent (Vista and Win 7 by default, Win8+ with extensions). BitBlt() works if the source is a memory DC that contains a 32bpp bitmap with an alpha channel. GDI+ works aswell.

How to verify font created by Windows?

I'm using the ChooseFont system dialog to populate a LOGFONT structure that is passed to CreateFontIndirect and the resulting font handle is selected into the device context and used. But it doesn't resemble the requested font in any way (well, OK, similar character sets, but otherwise not the same). Here's an image of the screen showing the ChooseFont dialog selecting an old DOS-style VGA font and in the background (behind the ChooseFont dialog) shows the font that I got when I selected the values shown in the dialog:
Notice that the Sample in the dialog and what Windows puts on the screen when the created font is selected into the DC are quite different. This doesn't happen for ALL fonts, only some of them, which is why I'm trying to correct and/or detect this.
I've tried getting the LOGFONT for the new font from the DC using (GetCurrentObject and GetObject) and it is identical to my request, except that the lfQuality has changed to NONANTIALIASED_QUALITY from anything else I've tried setting it to.
I have a kinda two part question:
How can I force Windows to use the font I've selected. Obviously there is a way, or it wouldn't look right in the ChooseFont dialog, either.
If no one can answer #1, how can I reliably find out that Windows has selected a totally wrong font, when asking Windows for the font info about the created font when selected into the device context doesn't work?
EDIT: July 8
If this helps at all, my basic calling sequence is:
LOGFONT lf;
CHOOSEFONT cf;
HFONT hf;
cf.lpLogFont = &lf; // plus other necessary stuff
ChooseFont( &cf );
hf = CreateFontIndirect( &lf );
SelectObject( hdc, hf );
ExtTextOut( hdc, ... );
Then, when I use the font, it doesn't always match what I requested. At all. (I just tried using Arial Monospaced MT and was rewarded with Courier -- Lucida Console would be a better substitute, at least it doesn't have serifs!) I don't do ANYTHING to the DC other than call GetDC(). I don't call any GDI setup/configuration functions, either, so I'm in whatever default mode one gets with a standard Windows program written in C to the WIN32API.
I've discovered that the Windows version of PuTTY shows the correct fonts while my program doesn't, but I have not yet been able to find anything different between the functions/parameters it uses to handle font creation and the way I do it. I'll keep looking though. Thanks to anyone who's given my question any thought, with or without suggestions. :-)

Rendering issue in WPF window while dragging

I have WPF window in which my Direct3D engine render. WPF Window I start from my engine, which I develop on C++/CLI.
I have 2 displays and when I move window between them, part of the window became white and not update until I am not stop dragging it (like on screen shot).
Does somebody know how to fix this issue?
It will be hard to post code here as it is a lot of code, but I will try:
I use managed C++ and unmanaged in one project:
So, I add .Net dll`s to have access to the WPF window:
Window^ wnd = gcnew Window();
wnd->Width = 1280;
wnd->Height = 720;
wnd->Show();
WindowInteropHelper^ helper = gcnew WindowInteropHelper(wnd);
HWND WPFHwnd = (HWND)helper->Handle.ToPointer();
HINSTANCE hinstance = (HINSTANCE)Marshal::GetHINSTANCE(this->GetType()->Module).ToPointer();
engine->SetHisnstanceHWND(WPFHwnd, hinstance);
engine->InitializeSystem(wnd->ActualWidth, wnd->ActualHeight);
engine - this is unmanaged class which incapsulates all work with rendering.
Further it is a stardard d3d rendering loop. Nothing special.
It render OK, but when I resizing or move window, it draw a part of it like this (with white). When I stop resizing or moving - all OK again.
My question is: is it possible to get rid of this effect or not?
UPDATE:
I hooked the wndProc if the WPF window and try to use UpdateLayout() when size changing, but this has no effect. Seems window is not react on any intervention.
Well, it sounds like your engine is receiving WM_ERASEBKGND and it clears the window. After you release the window, it sends WM_PAINT and everything is clear again. That's what I believe might be happening.
In order to test this theory, you can handle that message and return true. Put that to your engine message handling routine:
case WM_ERASEBKGND:
{
PAINTSTRUCT pss;
BeginPaint(hWnd,&pss);
EndPaint(hWnd,&pss);
return true;
}
You can use WinSpy++ to check out what messages are delivered to underneath window. If you want to see why the background is whited out, you can do it through ProcessMonitor and see what API calls are being issued. You're probably interested in API calls that include the color white.

Win32 CreateWindowEx() window icon not showing properly

I create my window using CreateWindowEx, but I only get an icon in the task bar; both the window's title bar and the icon that shows when I Alt+Tab show this type of dummy icon: . I set both the hIcon and the hIconSm fields in the WNDCLASSEX to the value returned from ::LoadIcon(hInstance, IDI_APPLICATION) (not NULL).
The .ico file itself was made out of a .png which I genereated through http://converticon.com to 16x16, 32x32 and 96x96 (what are the recommended sizes btw?). Could it be that I'm using the wrong sizes or color depth? If so, why does it work in the task bar (different size)? Thanks!
The icon must be defined as a resource somewhere. In your resource header there should be a line like this:
#define IDI_MYICON 1000
Then in your call to LoadIcon() it should be something like:
wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_MYICON));
If you're using Visual Studio it's pretty easy to add resources. Just right click Resources in the solution explorer.

Resources