The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: donkey on April 09, 2011, 09:52:15 AM

Title: Little test
Post by: donkey on April 09, 2011, 09:52:15 AM
I was bouncing around the idea of putting more "wow" into my current project and thought dialogs without title bars and gradient backgrounds would be cool. Here's the test piece I wrote to figure it out if someone wants it for their project. Can't guarantee that it will run on every system, certainly not 9x systems, but some might find it usable. Think I'll round the corners for the final version though...

Title: Re: Little test
Post by: Vortex on April 09, 2011, 09:56:56 AM
Hi donkey,

Your project works fine on my Win XP SP3 :U
Title: Re: Little test
Post by: dedndave on April 09, 2011, 01:23:58 PM
very cool, Edgar - XP MCE2005 SP2
Title: Re: Little test
Post by: FORTRANS on April 09, 2011, 01:26:12 PM
Hi,

   Seems to work as intended with Win 2000.  It does look odd,
though I guess that is what was wanted.

Cheers,

Steve N.
Title: Re: Little test
Post by: hutch-- on April 09, 2011, 03:54:52 PM
Works fine here, XP SP3.
Title: Re: Little test
Post by: Neil on April 09, 2011, 03:57:50 PM
Works O.K. Win 7 64 Bit SP1. Looks very odd.
Title: Re: Little test
Post by: RuiLoureiro on April 09, 2011, 05:13:17 PM
works fine on my XP SP3
Title: Re: Little test
Post by: donkey on April 09, 2011, 05:56:21 PM
Well, I tried the rounded corners and it looked good so I'll post the rounded one here. To do rounded corners I had to use a Dialog As Main type approach instead of the straight dialog since I needed to use a NULL brush for the dialog and don't want to make it an application global thing. I also cleaned up the interface a bit, put an edge below the "new title bar" and no longer allow the window to be moved except from that area, also shamelessly stole a close button image from Windows 7. Finally, I changed it to use a back-buffer to paint the window, always a good practice in case of slower machines. The limiting of the drag area is so that if you require it you can add a custom size grip or frame to the window, its not a big deal to write one if you need it. Its looking pretty good though...

(http://img691.imageshack.us/img691/9182/gradwin.jpg)

The "new title bar" is of course not a title bar at all and is entirely within the client area of the window. This means you can put graphics, menus or anything else in there.

Not sure what's up with Win2K and generally I don't support that OS but it should look fine. I don't have a copy of 2K anymore that I can test on. I am writing it on Win7 64 bit and it looks fine here.
Title: Re: Little test
Post by: dedndave on April 09, 2011, 09:51:57 PM
it behaves very strangely when i move it around, Edgar
there are remnants, especially on the right side
and, when i move it to the lower part of the screen (partly not visible), it does not want to move back
see if you can see the same thing
if not, i will try to do a better job of describing it   :P
Title: Re: Little test
Post by: donkey on April 09, 2011, 10:18:16 PM
Hi Dave,

I'm not having the same problem here on Win7 Ult. 64 bit. I've noticed that in XP mode the mouse tends to outrun it, I haven't figured out a solution for that yet. If you move the mouse back over the title bar it should move without pressing the button, that is the indication that its been outrun. The same thing happens to Windows stuff but somehow they make it snap to the mouse afterward, I have to figure out how they do that.
Title: Re: Little test
Post by: donkey on April 09, 2011, 10:29:54 PM
Try this one Dave,

I think that what Windows does is to capture the mouse during the move. It has solved the problem on my machine

Title: Re: Little test
Post by: jj2007 on April 09, 2011, 10:39:46 PM
Works perfectly now (XP SP2).
Title: Re: Little test
Post by: donkey on April 09, 2011, 11:16:56 PM
Thanks Jochen.

Dave,

I've noticed the artifacts your taking about. In some cases the rounded corners are filled and in others the drawing at the edges is incomplete. The problem doesn't show up on either Win7 or Vista, however its a bit severe in XP mode under some circumstances, specifically if there is high disk access or running processor intensive tasks while moving the window. I am trying to track it down but frankly I don't even know where to start. Even after the window has been invalidated the problem persists and it is not redrawn properly. I suspect an issue with regions under XP but can't find any reference to a known bug or KB article so this could take a while to track down. Perhaps I have to force an erase background after the button is released, I'll get back to you.

EDIT: Reading through the docs I found this:

QuoteIf hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.

It appears to be the source of the problem. Not sure how to erase a background that is transparent though...

EDIT:

A little further along, it seems that the width and height of the region have to be increased by 1 beyond the client rectangle. This gets rid of the edge artifacts. For the corners I still have not found out how to erase them with a NULL brush. Windows had to make allowances for this somehow, I can't find any help on it though and it only is an issue in XP mode as far as I can tell, at least it doesn't happen in either Vista or Win7 so there must have been a GDI change at some point to correct a problem but no KB article for it.
Title: Re: Little test
Post by: jj2007 on April 10, 2011, 12:10:48 AM
Quote from: donkey on April 09, 2011, 11:16:56 PMNot sure how to erase a background that is transparent though...

Perhaps you need to keep a copy of what's under the dialog, and restore it to "erase" the background.

By the way: no strange effects on my system, the second version runs very smoothly :U
Title: Re: Little test
Post by: donkey on April 10, 2011, 12:12:48 AM
Hi Jochen,

Could you try to move the dialog partially  off screen then slowly move it back on, are the corners still round ?
Title: Re: Little test
Post by: jj2007 on April 10, 2011, 12:15:46 AM
Quote from: donkey on April 10, 2011, 12:12:48 AMthen slowly move it back on, are the corners still round ?

Hi Edgar,

No, they come back squared. Had not seen that before, sorry.
Title: Re: Little test
Post by: dedndave on April 10, 2011, 12:29:13 AM
it appears that part of the move problem is fixed, Edgar
i still get the remnants
when i open the program, it is against my desktop as a background
to see the remnants, i move it over a white area
it seems to drag desktop content with it   :bg

(http://img806.imageshack.us/img806/1605/edgar3.png)

in this case, it opened over firefox with the forum showing - lol
that is the lower part of the right hand side
Title: Re: Little test
Post by: donkey on April 10, 2011, 01:12:54 AM
Hi Dave,

The side stuff I hope is solved, I just wasn't going to attach the solution until I figure out the corners. I am certain that corner issue is a problem with erasing the background, there are many many places at MSDN that indicate that when using a NULL brush I have to erase the background myself but I can't seem to get how to do it so it stays transparent. Its frustrating because I think I have gone through all of the standard ROPs and am now using the non-standard ones.

Here's the solution (I hope) to the edge issue, still working on the corner problem...

Title: Re: Little test
Post by: hutch-- on April 10, 2011, 01:30:19 AM
Edgar,

There are still repaint issues with the last one on XP SP3. Fails the slow drag test from off the screen, also has problems with dragging another window over it in that the corners appear as a black reverse radius.

Overlap it with another window them click back onto part of it and the overlapped part repaints correctly.
Title: Re: Little test
Post by: donkey on April 10, 2011, 01:38:25 AM
Hi Steve,

Yeah, there is a fundamental difference in the way XP handles background erasing that I can't seem to get a handle on, the edge issue I hope is fixed but the rounded corners are giving me fits. I could go the alpha blend route but that's normally a bigger can of worms and this way works so nicely in Vista and Win7 where apparently the problem is fixed. The problem appears to be that the window has a NULL brush so when Windows paints it it will use part of the desktop or object behind it, when its moved it should update the background but doesn't. I think that I will have to capture the desktop and paint the appropriate portion of it into the after the gradient fill with an inverted region. An incredibly complex paint process just to take care of something that is the responsibility of the OS.
Title: Re: Little test
Post by: dedndave on April 10, 2011, 03:13:17 AM
that method is probably do-able, Edgar
but, i think it is much worse than you think
it wouldn't be too bad if it was just your window and the desktop
but, if you take into account the z-order of multiple windows - well - let's go back to an overlayed window - lol
keep in mind that the content of these other windows may change at any time
the dynamics of capturing would be terrible
Title: Re: Little test
Post by: donkey on April 10, 2011, 03:18:36 AM
Quote from: dedndave on April 10, 2011, 03:13:17 AM
well - let's go back to an overlayed window - lol

Well, at worst I can go back to the square window but I haven't given up yet, there has to be a way or I'll just have to use alpha blending which is what I was trying to avoid. The alpha blend API (what there is of it) seriously sucks and is so counter intuitive that I would rather spend a week trying to get it done my way.

BTW are the jaggies fixed on the sides and bottom of the window on your system ?
Title: Re: Little test
Post by: dedndave on April 10, 2011, 04:58:45 AM
yah - that part is fixed   :U
good luck with the corners   :P
Title: Re: Little test
Post by: MichaelW on April 10, 2011, 05:37:56 AM
Running the EXE from reply #10 under Windows 2000, the only problem I can see is what appears to be random garbage in the 1-pixel wide strips on the right and bottom edges of the window. I don't know if it's the same problem, but this reminds me of a problem with the same symptoms that I had with  FillRect (http://msdn.microsoft.com/en-us/library/dd162719(VS.85).aspx), where I found the solution in the remarks section:
Quote
When filling the specified rectangle, FillRect does not include the rectangle's right and bottom sides. GDI fills a rectangle up to, but not including, the right column and bottom row, regardless of the current mapping mode.

Once I extended the right and bottom coordinates by one, the random garbage disappeared.
Title: Re: Little test
Post by: drizz on April 10, 2011, 10:51:38 AM
Quote from: donkey on April 10, 2011, 01:38:25 AM... the rounded corners are giving me fits.
Call SetWindowRgn (not in paint loop).

+ I would look into the border metrics for the current theme... GetSystemMetrics
+ UxTheme Api
Title: Re: Little test
Post by: donkey on April 10, 2011, 01:37:25 PM
Hi Drizz,

Thanks very much. I had figured it out shortly before going to bed last night but not yet modified the code. Stupid thing was I looked through some of my own example code and found the solution. Must be getting old or something because I found at least 20 apps that I wrote that used SetWindowRgn (http://img860.imageshack.us/img860/3091/starac.gif). I sometimes tend to over-complicate things even when the solution is right before my eyes.

At any rate, new test...
Title: Re: Little test
Post by: hutch-- on April 10, 2011, 02:02:42 PM
Edgar,

This one works fine.
Title: Re: Little test
Post by: donkey on April 10, 2011, 02:08:39 PM
Thanks Steve,

Its freaking embarrassing to have missed that API. Changed the program to set the height of the new title bar using a constant (TITLEBARHEIGHT), this is where it really comes in handy if you want say a drop-down combo in the title bar. Also added an icon that resizes based on the height.
Title: Re: Little test
Post by: Bill Cravener on April 10, 2011, 04:43:31 PM
Now thats damn cool Edgar! I used CreateRoundRectRgn followed by SetWindowRgn in my little example PasteIt to round the corners here: http://www.quickersoft.com/examples/PasteIt.zip

I did this:

                 ;------------------------------------------
                 ; Round the corners of our window space
                 ;------------------------------------------
                 invoke CreateRoundRectRgn,0,0,600,300,30,30
                 invoke SetWindowRgn,hWin,eax,TRUE
                 ;------------------------------------------
Title: Re: Little test
Post by: donkey on April 10, 2011, 05:17:12 PM
Thanks Bill,

I have experimented a bit and found that using a straight dialog is pretty much the same, there is no need for the NULL brush or to change anything in the dialog class. Here's the result. There are a few advantages to using dialogs as opposed to windows since they are a bit easier to use and for the app I plan to use them in it won't take a rewrite.

Title: Re: Little test
Post by: donkey on April 10, 2011, 08:56:18 PM
I've found that within my project the dialog looks pretty cool. However, since the background is gradient filled, static controls don't look right as they have the dialog gray background. In order to fix this I subclassed the static controls. Now setting the subclass for each control is a pain in the arse so I did them in an enumeration.

Added the following to WM_INITDIALOG:

invoke EnumChildWindows,[hwnd],offset EnumChildProc,offset StaticSubclass

New procedures:

EnumChildProc FRAME hwnd, lParam
LOCAL szClassName[256]:%TCHAR

invoke GetClassName,[hwnd],offset szClassName,256

invoke lstrcmpi,offset szClassName,"Static"
jnz >>
invoke GetWindowLong,[hwnd],GWL_WNDPROC
invoke SetWindowLong,[hwnd],GWL_USERDATA,eax
invoke SetWindowLong,[hwnd],GWL_WNDPROC,[lParam]
:
mov eax,TRUE
ret
endf

StaticSubclass FRAME hwnd,uMsg,wParam,lParam
LOCAL rct:RECT
LOCAL szText[256]:%TCHAR ; may want Unicode some day so use TCHAR instead of B
LOCAL ps:PAINTSTRUCT

.WM_PAINT
cmp D[uMsg],WM_PAINT
jne >>.DEFPROC
invoke BeginPaint,[hwnd],offset ps
invoke SetBkMode,[ps.hdc],TRANSPARENT
invoke SetTextColor,[ps.hdc],0
invoke GetClientRect,[hwnd],offset rct

invoke GetWindowLong,[hwnd],GWL_USERDATA
invoke CallWindowProc,eax,[hwnd],WM_GETTEXT,256,offset szText

invoke GetStockObject,DEFAULT_GUI_FONT
invoke SelectObject,[ps.hdc],eax
push eax
invoke DrawTextEx,[ps.hdc],offset szText,-1,offset rct,DT_CENTER + DT_VCENTER,NULL
pop edx
invoke SelectObject,[ps.hdc],edx
invoke EndPaint,[hwnd],offset ps
xor eax,eax
ret

.DEFPROC
invoke GetWindowLong,[hwnd],GWL_USERDATA
invoke CallWindowProc,eax,[hwnd],[uMsg],[wParam],[lParam]
ret
endf
Title: Re: Little test
Post by: donkey on April 12, 2011, 01:43:31 AM
This is how the dialog looks in my RadAsm addin (which is nearing completion). The labels are static controls using the subclass above, note the rounded buttons, I thought that added a bit of pizazz to it as well.

(http://img69.imageshack.us/img69/8287/finalje.jpg)

For the rounded buttons the following code was added to EnumChildProc, no subclassing was necessary for the buttons.

:
invoke lstrcmpi,offset szClassName,"Button"
jnz >>
// Make the buttons pretty too
// Note that only the buttons with the WS_CLIPSIBLINGS style
// will show the modification so that style is used to
// regulate which buttons are affected
invoke GetClientRect,[hwnd],offset rct
// Remove the button borders or it looks silly
sub D[rct.right],2
sub D[rct.bottom],2
; adjust the origin of the region to left 2 and top 3 when creating it
invoke CreateRoundRectRgn,2,3,[rct.right],[rct.bottom],10,10
invoke SetWindowRgn,[hwnd],eax,TRUE
:
Title: Re: Little test
Post by: dedndave on April 12, 2011, 02:36:39 AM
now, you're showing off   :P