|
Hello!
I have been having trouble understanding the function DrawText as defined in the MSDN Library:
int DrawText(HDC hDC, LPCTSTR lpString, int nCount, LPRECT lpRect, UNIT uFormat);
Can someone provide a simple example as to what this function does? Any help given me to better understand this function is appreciated.
Mike
|
|
|
|
|
The first parameter is a device context. It's a handle to whatever you're drawing on. It could be the screen, a bitmap, printer, etc.
The second parameter is the string you want to draw - no mystery there.
The third parameter tells DrawText how much of the string it should draw - i.e., the length of the string. You can pass it -1, if you want it to draw the entire string.
The fourth parameter is a bounding rectangle, in which the function will draw the text. The coordinates of the rectangle are in whatever units your device context is set to use. A screen device context would typically use pixels as coordinates.
The last parameter tells DrawText how it should go about drawing the string. The DT_SINGLELINE flag specifies that the text should not be broken into several lines. DT_RIGHT would align the text to the right hand side of the bounding rectangle. DT_END_ELLIPSIS tells DrawText to draw "..." on the right hand side, in case the entire text does not fit in the bounding rectangle. These are just some of the flags that exist. I suggest you look at the MSDN documentation for more information. The flags can also be combined using the or operator. For instance: DT_RIGHT | DT_SINGLELINE would tell DrawText to draw the text on one line, and align it to the right.
--
The Show That Watches Back
|
|
|
|
|
Did you see DrawText on MSDN it has one example of it
|
|
|
|
|
Does anybody know how to prevent child windows from drawing over a certain region of the parent window? My top level window has custom borders, when resizing the child controls are moved/resized. In some instances the child control will paint over the custom borders, I would prefer the children to instead be cropped leaving the borders intact. I know this can be avoided using MINMAXINFO but is there any way to do this using regions and/or WM_PAINT/WM_ERASEBKGND?
|
|
|
|
|
How about using the SetWindowRgn() to set the fdrawable region in the window?
Mark
|
|
|
|
|
I don't see how that would work. I have basically redefined the whole client area of the window. The new borders are rounded. I am already calling SetWindowRgn() to create a rounded window. I have at my disposal a window region, a client region, a border only region and a child clipped region. Basicaly I only want to allow the children to draw within the client region, but I have no idea where and how to set this.
I have tried everything I can think of within WM_PAINT, but nothing seems to be working. Could you suggest anyplace else where I might set/exclude a region?
|
|
|
|
|
waldermort wrote: I am already calling SetWindowRgn() to create a rounded window
What region do you set with SetWindowRgn()? It should be the client region, not the window
region, right?
Mark
|
|
|
|
|
Mark Salsbery wrote: It should be the client region, not the window
region, right?
Wrong!
|
|
|
|
|
I use the 'window region' to set the window region. The 'client region' is the 'window region' excluding the border (there is no caption bar), this is the only place I want child controls to be able to draw. The 'clipping region' is the 'window region' excluding the regions of the child controls which is selected into the DC on WM_ERASEBKGND to prevent flickering (much the same as WS_CLIPCHILDREN).
Idealy, I would like to select the 'client region' into a DC somewhere to prevent children drawing outside the region. But so far I have not had any success. I created the 'border region' hoping to validate it before child controls are painted, but it didn't work.
|
|
|
|
|
Ok another couple ideas (probably as stupid as my other ones)
ExcludeUpdateRgn() specifying the border-only region.
In the parent window's WM_PAINT handler (or WM_NCPAINT?) call ValidateRgn() specifying the border-
only region.
EDIT: You tried that already
|
|
|
|
|
I saw this function on MSDN but I cannot figure out how it's supposed to be used. It accepts a HDC and a HWND, where does the HRGN come into play?
|
|
|
|
|
Haha I'm looking into that as we speak (because I won't be able to sleep until you get this
working and I'm really curious how it's done. Windows does it all the time - it can't be too
difficult!
|
|
|
|
|
From all I can tell, selecting a region into the DC, then calling Exclude prior to painting effects what parts are painted, but it doesn't propegate down to the children.
Another thing I have tried is to set the children as HWND_BOTTOM since I am already clipping the parent, in theory they should only be visible through the clipped holes, but that isn't working either.
|
|
|
|
|
OK...
Since the whole notion of a "client area" in a window is based on WM_NCCALCSIZE notifications,
therefore completely hardwired to RECTS (dammit ) how about this...
Use a frame window/ client window method.
Frame window class is the border - it has a transparent client area by just returning TRUE from
WM_ERASEBKGND (to prevent flicker). Its shape is set with SetWindowRgn().
Client window class is borderless, its shape is set with SetWindowRgn() as well, but using the
client region you already have, which I presume is slightly smaller than the window region.
It has the WS_CHILD style and is a child of the frame window.
All child windows will be children of the client window so they won't draw outside its region.
The frame window just needs to position the client window in its client area in response to
WM_SIZE.
Would that work?
Mark
|
|
|
|
|
I had the same idea last night, but I thought it was a bit of an overkill. Though I may end up having to do it this way. One thing I am going to try first is allow the child controls access to the 'client region' and take this into account when drawing. Another thing I could try is to resize the child controls, though this method will only work when the client edge is horizontal/vertical.
The layered windows if of no use to me since a majority of my users will be Win98 users. I must get around to creating a Win98 compatible API equivlent.
I will give this another try later, I have to work now, and let you know how it goes.
|
|
|
|
|
|
Just an update to the problem. I still have not been able to resolve it. I tried your suggestion of having a client window as a child of the parent, which didn't work. The first problem was trying to resize and position the window so that it exactly covers the client area, not quite so simple when dealing with shape changing windows. Then came the problem of sending messages between the two, and which of the two should deal with it. In the end, I managed to get it set up right, but the child controls still overlapped, I think they were leaking inot the neighbouring DC. So now I am right back to square one.
|
|
|
|
|
I finally managed to get it done. The solution was actually quite easy. Instead of drawing to the Child window HDC, I get the DC of the parent and draw directly to that. Since the WM_PAINT and WM_ERASEBKGND messages only paint to the parents DC, the window appears transparent yet has full functionality. Upon getting the DC it's simply a matter of selecting the 'client region' among others into the DC which prevents drawing on the borders.
I'm not yet sure how this will work with nested windows, but it shouldn't cause to many problems.
|
|
|
|
|
waldermort wrote: Upon getting the DC it's simply a matter of selecting the 'client region' among others into the DC which prevents drawing on the borders
Are you kidding? I thought you tried that originally!!
That was the first suggestion I responded with.
LOL Glad you got it working and thanks for the update
Mark
|
|
|
|
|
The hurdle was getting ahold of the correct DC to draw to. As you know each window comes with it's own regions, client area DC etc... The DefWindowProc for some controls will check the wParam for a HDC within it's WM_PAINT, but most don't. Besides that, MSDN states that users should not send this message directly but rather send it through an api such as InvalidateRect(). Other than Owner drawn and subclassing, there is no method for us to control how a child window draws.
In answer to your first response, how can you select a region into the DC before DefWindowProc starts it's WM_PAINT or WM_ERASEBKGND. Even after subclassing, I have had to redirect all the drawing to the main windows DC, which basically means, for each control I add, I have to subclass it.
But the end result is well worth the effort. I am now half way to completeing a resizable skinned window library in non MFC.
|
|
|
|
|
Right I got it haha. I was confused once again.
Makes sense now. I wonder if using CS_OWNDC on the background window would work...would windows
use that dc to draw to, and if so, would it select its own clip region into it...
I'll have to try that when I get a chance
Mark
|
|
|
|
|
Hi,
How to send/post a message to the parent view window
so that I can calculate sum of variables which belong to the parent view window
Thanks
Prithaa
|
|
|
|
|
|
Surely there must be a harder way!
Mark
|
|
|
|
|
prithaa wrote: How to send/post a message to the parent view window...
By using SendMessage() or PostMessage() .
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|