|
Actually, all you need is the DC of the desktop window. Compute the invalid rect (you already have this), create a rectangular clip region and select it into the desktop's DC, then invalidate the desktop (and optionally force an immediate repaint by calling UpdateWindow() ).
I hope what I've suggested isn't overkill.
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
No it is not overkill.
This is what I have so far, and still no result. Am I missing something?
HWND hWndDesktop = ::GetDesktopWindow();<br />
HDC hDcDesktop = ::GetDC(hWndDesktop);<br />
<br />
int nX = BOUND(m_ptZoom.x, m_nxZoomed / 2, m_nxScreenMax - (m_nxZoomed / 2));<br />
int nY = BOUND(m_ptZoom.y, m_nyZoomed / 2, m_nyScreenMax - (m_nyZoomed / 2));<br />
<br />
RECT rBounding, rErase;<br />
rBounding.left = nX - m_nxZoomed / 2;<br />
rBounding.top = nY - m_nyZoomed / 2;<br />
rBounding.right = rBounding.left + m_nxZoomed;<br />
rBounding.bottom = rBounding.top + m_nyZoomed;<br />
::InflateRect(&rBounding, 1, 1);<br />
<br />
::CopyRect(&rErase, &rBounding);<br />
::MapWindowPoints(NULL, hWndDesktop, (LPPOINT)&rErase, 2);<br />
HRGN hRegion = ::CreateRectRgn(rErase.left, rErase.top, rErase.right, rErase.bottom);<br />
::InvalidateRgn(hWndDesktop, hRegion, TRUE);<br />
::UpdateWindow(hWndDesktop);<br />
<br />
::DeleteObject(hRegion);<br />
::ReleaseDC(hWndDesktop, hDcDesktop);<br />
|
|
|
|
|
InvalidateRgn() adds the specified region to the existing invalid area. Selecting it into the desktop window's DC using CDC::SelectClipRgn() will replace (i.e. redefine) the invalid area. I think this is what you want to do. (Fingers crossed).
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Not that either.
|
|
|
|
|
Just for grins, can you TRACE() the value of rErase and ensure it's not the size of the desktop?
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
I had previously tested the coordinates and they are not size of screen.
They are something like L=317,R=450,T=400,B=550 but nothing NEAR the size of the screen.
With the invalidate region code, I have not been able to get anything to erase, whether my rect was drawn on the desktop window or onto an application window.
Thansk for your help. It is probably some simple API or combination of them we are both failing to realize.
I would think this is possible, without lengthy enumeration of windows on the desktop, descending into children, etc.
Worst case scenario, I invalidate entire screen. I already know that works.
|
|
|
|
|
Do you have a dual screen setup? Sometimes when I have the SQL Enterprise manager open at the same time as VS.NET, they get caught up in an "invalidation race". VS.NET invaldates something that triggers a total repaint. This in turn triggers the enterprise manager to do a total repaint, which in turn triggers VS.NET ad infinitum. Sometimes it just won't stop until I minimize either one of them. Freaky!
--
Schni Schna Schnappi! Schnappi Schnappi Schnapp!
|
|
|
|
|
No recursion here.
Just a single massive repaint of entire screen seems to work so far. I am trying to avoid that.
When I try the clipping, regions, etc. as suggested sto this point, NO repainting occurs reliably all the time. Bits and pieces of windows will repaint, but not all necessary areas
|
|
|
|
|
Did you notice this documentation for the hWnd parameter:
hWnd
[in] Handle to the window whose update region has changed. If this parameter is NULL, the
system invalidates and redraws all windows, and sends the WM_ERASEBKGND and WM_NCPAINT
messages to the window procedure before the function returns.
Is it the desktop window (i.e, the "background") you wish to redraw, or every visible window within an area?
If you intend to redraw the desktop window, I suggest you get a handle to the desktop window by calling GetDesktopWindow(), and then invalidate that window.
--
Schni Schna Schnappi! Schnappi Schnappi Schnapp!
|
|
|
|
|
Thanks for the note and suggestions.
Every visible window containing parts of its area within a specified area of the screen.
Speficially, only to invalidate the area of every window visible within the specific area. For exmaple, if I am in the middle of a window, it should not have to repaint is frame.
The combinations of what parts of which windows might be affected, given that I only have a rectangle representing a part of the screen, makes the effort almost more trouble than just telling the entire screen to repaint.
|
|
|
|
|
I'm sorry I cannot be of any assistance.
I must say that what you are doing sounds quite intriguing. What kind of software are you writing?
--
An eye for an eye will only make the world blind.
|
|
|
|
|
A feature-rich ugrade to the aging ZoomIn utility.
Do you have any suggestions for features you would like to see in it?
My starting point came from here
http://www.csc.calpoly.edu/~bfriesen/software/zoomin.shtml[^]
When you left-click on the ZoomIn window, you drag a 'outline' rectangle to another part of the screen, that is what you will view.
In most cases, a DSTINVERT PatBlt will draw/erase this rectangle. In other cases, though, I only know where it might have been drawn and not which combination of PatBlt will get the rectangle erased, so I am looking to tell the 'owner(s)' of that screen real estate that the area must be repainted. Trying to invalidate an 'area' of the screen is what is so problematic.
::InvalidateRect(NULL, NULL, FALSE);
works every time, but it causes the ENTIRE screen to repaint.
I could probably come up with a combination of EnumWindows/GetWindowRect/ScreenToCLient/IntersectRect/Invalidate loops that would get the job done, but then is that much faster or efficient than just telling Windows to invalidate the entire screen?
I might do that as an exercise and then profile it just for kicks.
I was hoping some graphics wizard might point me to the magical GDI API I was overlooking. There might not be one, though
|
|
|
|
|
As I do a lot of GUI work, this is the kind of tool that I would use extensively. Features that I'd want in such software are:
* Pixel color values in both decimal and hexadecimal
* Coordinate display in both client coordinates and screen coordinates
* Grid and no grid
* Non-restricted zoom in level, and not just x2, x4, x8 like some tools insist
* Saving capabilities in case one wants to compare visual changes with earlier renderings
As for the problem at hand, EnumWindows is probably a good solution. I don't think it'll degrade performance so much that it's noticable. But I agree, it's a shame that InvalidateRect doesn't work as one would expect.
Please let me know if you need bug testing etc. Is this an open source, free tool, or shareware project? If it's free, then please sign me up for a copy once it's passed Q&A!
--
An eye for an eye will only make the world blind.
|
|
|
|
|
An eye for an eye will only make the world blind...
But only if they recurse, otherwise the entire world would be half-blind
|
|
|
|
|
Instead of InvalidateRgn use RedrawWindow.
It can invalidate non client area.
|
|
|
|
|
Thank you so very much! That is just what the GUI Doctor ordered
This is what seems to work well enough.
<br />
HWND hWndDesktop = ::GetDesktopWindow();<br />
<br />
RECT rBounding;<br />
..set rBounding to rectangle in 'screen' coordinates that needs to be erased...<br />
<br />
::RedrawWindow(hWndDesktop, &rBounding, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
I can definitely see that the entire screen is not being repainted!
|
|
|
|
|
IIRC, invalidating a specific rectangle, windows will automatically setup a clipping region for you.
--
Schni Schna Schnappi! Schnappi Schnappi Schnapp!
|
|
|
|
|
I'm developing an in house application, and I want the user to be able to pause a journal file when it is being played back, by the using pressing PAUSE and resuming playing by pressing PAUSE again.
I have set hooks for journalrecord and journalplayback, and they both work ok, it would seem that once started to play a journal file cannot be paused, but can be stopped using ctrl+alt+del.
I'm using VC++ 6.0.
Any help would be much appreciated.
Phil
|
|
|
|
|
This[^] article might help you (look for the Other Considerations section). Windows sends a WH_CANCELJOURNAL message when you press Ctrl+Alt+Del or Ctrl+Esc. You need to monitor that and then store the current state somewhere. When the user hits Resume, you'd have to install the hook again and start playback from the stored state.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
WinMacro rocks! Thanks for making the source available.
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
|
i have a class which has partly implement the IDataObject interface.
i don't know how to finish the GetData(...) method
what should i do in it so it can support text copy/paste?
|
|
|
|
|
Hey all.
On my main dialog I have created a property sheet and added a couple of property pages to that sheet. I have a menu on the dialog that allows you to select options. I have an event handler in the main dialog that handles the clicking on those particular option buttons. What I want to be able to do is from the main dialog button event, send a message to one of the property pages telling it to do something (in this case, it would send a message saying "Refresh your view now"). I'm not really sure how to go about doing this. If anyone could enlighten me I would really appreciate it.
TIA
Shultas
|
|
|
|
|
Well... You could use PostMessage or SendMessage with a custom (WM_USER) message to transfer the data in windows messages. But surely you have a set of objects for your property pages declared somewhere in your dialog or propery page. So can't you just define a function in the class of the property page, and then call that from the parent dialog?
Joel Holdsworth
Wanna give me a job this summer?
Check out my online CV and project history[^] - now available in MSWord format![^]
|
|
|
|
|
Anyone care to make some money? I need the following written in C++ for a class that I hate.
Modify the mortgage program to input the amount of the mortgage, the term of the mortgage, and the interest rate of the mortgage. Display the mortgage payment amount. Then, list the loan balance and interest paid for each payment over the term of the loan. On longer-term loans, the list will scroll off the screen. Do not allow the list to scroll off the screen, but rather display a partial list and then allow the user to continue the list. Allow the user to loop back and enter new data or quit. Insert comments in the program to document the program. This program should still be a procedural C++ program.
|
|
|
|