I'm trying to create a simple Paint application using MFC. So everything working good and as expected. I have just one issue with resising, in fact when i re-size my window or minimizing it everything disappear and I got blank page. I found that this's caused by the OnDraw function, but I can't find how to deal with that issue.
The purpose of the OnDraw function is to recreate the drawing after the window has been resized/uncovered/unminimized. Your OnDraw function must be able to draw everything at any time. So the event handlers like OnLButtonUp should set variables that can be used by OnDraw. Then the event handlers can call Invalidate to cause a new OnDraw.
Related
I'm asking this question ahead of time, since I haven't gotten around to attempting an actual, real implementation yet. Win32 (C++) is turning out to be a colossal pain to program. But, my question is this:
I want to make my application's window become fully transparent with a dotted perimeter when resizing the window. How would I accomplish this? Think of what happens in Windows 3/3.1 (I believe it was this version) when resizing a window. Everything goes transparent, with a dotted-outline where the mouse is moving, then it repaints the entire contents. That's what I'm trying to achieve.
A while ago, I tried handling the WM_(ENTER/EXIT)SIZEMOVE messages and make use of SetWindowLong() to set the WS_EX_TRANSPARENT extended style, but my window became (indefinitely) pass-through, and when the window's focus was killed, it could never again regain focus.
Do I need to handle other messages like WM_NCLBUTTON(DOWN/UP)? I have a boolean flag to tell me when to halt drawing during resizing, and the logic for determining when I'm resizing works perfectly, but I cannot get the visuals to work. I'm not sure which parts of the Win32 API to actually use. I've done some research, and uxtheme.lib/.h seems promising, but I'm not sure how that would work with WM_NCPAINT, which I have been using with (some) luck.
EDIT
I need to clarify something, in case anyone was confused or unsure of what I meant. What I meant by the Windows 3.1/3 resizing scenario is that once WM_ENTERSIZEMOVE has occurred, the window (controls, caption, frame) should be made entirely invisible, and the window's nonclient-region's perimeter should display a dotted-outline of sorts. Then, only until the resize has been finished, when WM_EXITSIZEMOVE has occurred should the entire window (controls, caption, frame) be fully redrawn, updated, and returned to its normal, functional state. Sorry for any miscommunication!
I found the answer... After so long, finally found it. Here's where I found it! http://www.catch22.net/tuts/win32/docking-toolbars-part-2# - Hope it helps anyone else possibly in my shoes!
And it turns out that the solution was rather simple. In fact, the core concept of what is explained is near-completely what I was thinking, yet I just had no idea how to implement it. The solution involves overriding the default WM_NCLBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP (specifically when initiating a window movement) messages, and drawing a patterned rectangle which follows the position of the cursor. Then, afterwards, calling SetWindowPos or some other similar function to relocate the window.
Basically, block Windows from attempting to display anything graphics related until the resizing has been finished. Then, and only then, make Windows move the entire window in one huge, foul swoop.
Based on Remy's comment, there is a global option and corresponding registry setting for this, so perhaps try setting the registry setting when the move starts and restoring it when the move finishes.
Unfortunately this doesn't work as Windows appears only to pick up the setting on restart, broadcasting WM_SETTINGCHANGE also doesn't trigger it, which is a pity as doing something yourself that the OS already has an implementation of do is rather a poor state of affairs.
Let's say you want to add a little extra graphical info to a Windows control. For example, you want to add drag/drop functionality to a listview (using the procedure discussed here), but with horizontal lines signaling the drop/insertion points as the user drags an item. (The control belongs to your own application.)
Is there a safe way to subclass the control and draw onto it directly? In my limited experimentation in trying to do this, I encountered some problems. First, it wasn't clear whether I should call BeginPaint and EndPaint during the WM_PAINT message, since the control itself would be calling those functions once the message was passed along to the default procedure. I also inevitably encountered flickering, since some areas were being painted twice.
I thought a safer way would be just to create a transparent overlay window and draw on that, since that would avoid conflicts with the default paint procedure, but I thought I'd ask before going down that road. Thanks for any advice.
Single Document, the simplest MFC app.
The idea is that default CDC pDC is edited(colored) in some way from onDraw() function. When a user clicks on a number I want it to be displayed using colors from pDC.
If I use the default handler function OnKeyDown for WM_KEYPRESS I don't get a pointer for my edited pDC.
My question is how to access the edited pDC?
I am sure that there is a simple solution that I am missing, please help.
I am not 100% sure I understand the question correctly, but let me try....
The usual and recommended way in MFC to do what I think you want would be to handle all drawing in onDraw() only.
So, in the onKeyDown() handler, you would store the pressed key to a member variable (or maybe even push it to a vector or list of keys to be drawn) and then call Invalidate(false). That causes Windows to generate a WM_PAINT message to your window, which ends up being handled in onDraw(), where you can now draw the correct things based on your current member variable values.
It is also possible to create a CPaintDC outside of onDraw() and draw on that. But as said, usually in MFC applications, all drawing is kept in one place. Windows may request your app to redraw at any time and it does that with a WM_PAINT message.
I want to create an SDL window in an existing app. The problem I encounter is that at startup, after the SDL_SetVideoMode call, a black window pops up until the remaining of my application is initialized. This is ugly and I was wondering if there was a function which controls the hide/show of this window.
There doesn't seem to be such a function in SDL, however if there were, I'd likely make you see a window pop up and disappear right away, which you may also consider ugly. You'd better display some "Loading..." message in a window, or postpone SDL_SetVideoMode call to the point when your application is fully initialized. The former is better, as the user will know that he has actually launched an application and won't try to run it multiple times.
I suspect there must be a built-in way to do this, but my Google-fu has failed me.
I'm using a wxScrolledWindow, and I have to paint an unscrolled background picture behind the contents each time the window is scrolled. I've made a scroll handler like this...
void homewindow_t::onScroll(wxScrollEvent &evt) {
Refresh();
evt.Skip();
}
...which works to force it to redraw the entire window each time. Unfortunately, it draws the window before the scroll is handled, so the background is repainted and then scrolled up or down, screwing up the alignment. The documentation suggests that Refresh just invalidates the screen, meaning that the scroll handler must be forcing a redraw.
The only way around this that I can see is to handle the scrolling code myself, which I'd rather not do if I don't have to.
Ideas, suggestions, clues...?
The only general solution I've found to running code after an event is handled is to post a second, different event to the event queue before skipping the current event (so that it gets handled by the default handler), and handle that when it comes up.
However, perusing the wxWidgets source code, I've found an answer to my specific problem: there's a function, wxScrolledWindow::EnableScrolling. Although it's not obvious from the name, this will enable or disable the "physical scrolling," which is what forces the instant redraw. So calling EnableScrolling(false, false); in the window's constructor solves the issue entirely.
To paint a "fixed" background in wxScrolledWindow you should just offset the DC origin to compensate for scrolling before drawing it (and then reset it back, of course), there is really no need to deal with events at all.
However if you really need to define a "post handler", then there is a way to do it, see this blog post. While the API described in it will only be available in wx 2.9.5, you do the same thing in the previous wx versions manually using wxEVT_IDLE.