2

I want to make an application where I'd paint on the entire window. I use GDI+ for that purpose. Since I don't need it to have any border, I disabled it with SetWindowLong function, getting rid of any styles that would make it have a frame, like this:

SetWindowLong(hwnd, GWL_STYLE, 0);

It works fine as long as I don't try to actually paint something on that window myself. I tried processing WM_PAINT messages, WM_ERASEBKGND messages, even WM_NCPAINT (it doesn't do much though), but for some reason there's always some remaining of a border, or at least it looks like it. Something like this: My window

As you can see, there is a black rectangle with some kind of the frame at its bottom and right sides. It looks like the border was not completely drawn here, though it shouldn't be painted at all. The image here is just a blank black bitmap, but the problem is the same for normal pictures as well. It doesn't look the same for all messages I tried to process, but the result is pretty much identical - it ends up drawing some additional rubbish, as if it tires to draw damn frame no matter what.

This is how I process messages:

case WM_ERASEBKGND:
{
    drawer->DrawImage(image, 0, 0, width, height);
    return 0;
}  
case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint( hwnd, & ps );
    drawer->DrawImage(image, 0, 0, width, height);
    EndPaint(hwnd, &ps);
    return 0;
}

A drawer variable is a pointer to Gdiplus::Graphics class object, image is a pointer to Gdiplus::Bitmap object. I do believe these objects are valid since normal pictures loaded from files are shown properly (except for that damn frame).

It works fine if I enable styles that enable drawing window's frame, but I don't want to do that. I run out of ideas though and don't really know what to do. Never coding win32 apps staying up so late in the night.

EDIT: apparently the problem was in drawer variable after all. I figured that creating a Gdiplus::Graphics object once and associate it with window handle would be a good idea. But for some reason it looks like it doesn't get a new device context from associated window when it needs to (propably it just gets it once and then doesn't bother about it). So I tried creating a new object every time I want to paint something on the window and the rubbish's gone!
Anyway thanks for everyone who commented and tried to help, I really appreciate it.

PookyFan
  • 785
  • 1
  • 8
  • 23
  • 4
    Setting the window styles to `0` also clears fairly important ones like `WS_VISIBLE`. Without that style set, Windows won't try to paint your window. – Jonathan Potter Nov 20 '14 at 03:35
  • You need to set the window style before the window is even created if you want to eliminate the remnants of a border. – Mark Ransom Nov 20 '14 at 04:08
  • @Jonathan Potter: ShowWindow function works as well. Of course I can set this style as the only style I want my window to have, but it's not necessary. – PookyFan Nov 20 '14 at 11:12

1 Answers1

2

If you handle background painting yourself, you need to return 1 from your WM_ERASEBKGND handler. Something like this:

return 1L; // if in window procedure

or

return (INT_PTR)TRUE; // if in dialog box procedure

I also don't like the way you remove border. Try this instead.

It seems to me that you need splash screen but I haven't done that yet. Still this MSDN article could be exactly what you need.

If all fails, here are some other that can help you:

http://www.codeproject.com/Articles/15523/Own-thread-Win-splash-screen

http://www.codeproject.com/Articles/7658/CSplash-A-Splash-Window-Class

Quickest way to implement a C++ Win32 Splash Screen

http://code.logos.com/blog/2008/09/displaying_a_splash_screen_with_c_introduction.html

http://www.codeguru.com/cpp/w-d/dislog/splashscreens/article.php/c5029/Adding-a-Splash-Screen-to-Your-Applications.htm

Hopefully this helps. Best regards and good luck!

Community
  • 1
  • 1
AlwaysLearningNewStuff
  • 2,939
  • 3
  • 31
  • 84
  • These splash screens are kinda interesting, though I doubt they would come handy since I'd need to process lots of messages, and I wonder if I would be able to process them through another window's procedure that easily. – PookyFan Nov 20 '14 at 11:10
  • @PookyFan: The way I understand is that you need to `return NULL` in your `WM_NCCALCSIZE` handler to remove titlebar and caption. [See the remarks section.](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632634%28v=vs.85%29.aspx). – AlwaysLearningNewStuff Nov 20 '14 at 11:44
  • @PookyFan: I have just tried it and it works! Just return `NULL` from `WM_NCCALCSIZE` and window frame is removed! Still, the only way to close the window is through `ALT` + `F4` but notice that my window had `WS_OVERLAPPEDWINDOW` style. – AlwaysLearningNewStuff Nov 20 '14 at 11:51
  • @PookyFan: For closing the window, you can add a button to your window and use `DestroyWindow` and it will work ( I have tried it just now ). – AlwaysLearningNewStuff Nov 20 '14 at 11:57
  • Yeah, thank you, but I already fixed my issue. Still I'm glad you went ahead and checked it all in order to help me, I really do appreciate it. – PookyFan Nov 20 '14 at 12:23
  • @PookyFan: OK, no problem. I have read your update and your method is "fishy" in my opinion. What happens when you hover with the mouse over the position where maximize button should be? I think it will "pop" but maybe I am wrong. Test it just in case and please tell me what happens. Best regards. – AlwaysLearningNewStuff Nov 20 '14 at 12:29
  • Everything works just fine, nothing of the non-client area "pops", all I have is rectangle with my picture painted on it. No problems with moving it too (I handle moving that window by processing mouse messages). So I can hover wherever I want over that window, move it, minimise and maximise, and it looks ok all the time. – PookyFan Nov 20 '14 at 13:07