i wanted something a little different
i suppose it isn't that hard to just write a dialog box, but....
(http://img716.imageshack.us/img716/5570/custommb.png)
i followed a little code by J Brown, circa 2002, written in C
http://www.catch22.net/tuts/custom-messagebox
here we go - i found the original thread where Erol pointed us to it :P
http://www.masm32.com/board/index.php?topic=13745.msg108004#msg108004
i am going to play some more to see if i can change the icon
if so, you can select the MessageBox parameter icon to pick the sound you want
then, pick a different icon, as desired
Dave,
The icon is easy, use MessageBoxIndirect().
i noticed that function, Hutch
but i didn't see a way to "disconnect" the sound from the icon
i suppose you could try MB_ICONQUESTION in the style member to elimiate the sound
then, try setting the MB_USERICON flag to specify an icon
seems like there might be a confilct, there :P
what i noticed about using a CBT hook was that you got the handle to the dialog window in wParam
should be able to do a lot with that
SetWindowLong, if nothing else
that seems to apply to a title bar icon, though
after a certain point, you may as well make your own dialog box :bg
the code posted is small enough to make it worth while
If really you want a special messagebox,the better way is to made it.
Source code could be just pick up on sample:
http://www.masm32.com/board/index.php?topic=17217.msg144170#msg144170
after that,you have the choice to made it classic (using system resource) or not.
Dave,
It takes the same style as an ordinary message box but you specify a resource icon instead. Then use the button combination you want and if you have code to do it, change the text then.
ok - after mashing all the buttons :P
much to my surprise, all the standard message box icons are associated with a sound
of course, there has to be one selected in your current theme to hear them all - lol
;MB_ICONSTOP 10h Critical Stop
;MB_ICONERROR 10h
;MB_ICONHAND 10h
;
;MB_ICONQUESTION 20h Question
;
;MB_ICONEXCLAMATION 30h Exclamation
;MB_ICONWARNING 30h
;
;MB_ICONINFORMATION 40h Program Error
;MB_ICONASTERISK 40h
in my version of XP, the standard theme has no sound selected for Question
so, i thought that icon selection had no sound associated with it
i created a temporary theme with all the sounds fired up to test them
now, as for MessageBoxIndirect...
in addition to the standard MB_ICON* selection constants, they allow the use of MB_USERICON in the dwStyle member
if you select MB_USERICON with one of the standard icons, both are ignored and no icon is displayed
you can select MB_USERICON, set hInstance to NULL, and use one of the system icons
if you use MB_USERICON, no sound is associated with the MessageBox
in other words, if you want a sound and a different icon, you'd have to use PlaySound or a similar function
you can play themed sounds by using SND_ALIAS for the PlaySound fdwSound parameter
and you have to use a pointer to a theme-name string that matches those in the registry for the pszSound parm
INVOKE PlaySound,chr$('SystemAsterisk'),NULL,SND_ALIAS
a partial list - i am sure there are others...
AppGPFault
CCSelect
Close
CriticalBatteryAlarm
DeviceConnect
DeviceDisconnect
DeviceFail
LowBatteryAlarm
MailBeep
Maximize
MenuCommand
MenuPopup
Minimize
Open
PrintComplete
RestoreDown
RestoreUp
ShowBand
SystemAsterisk
SystemExclamation
SystemExit
SystemHand
SystemNotification
SystemQuestion
SystemStart
WindowsLogoff
WindowsLogon
i do still have one question
some of you guys with non-English versions of windows can help me out :P
with MessageBoxIndirect, you can specify a language
the documentation is a little unclear about exactly what LANG_NEUTRAL (0) means
i am guessing that means generic English
here is a test program to find out....
EDIT
it is the language on the buttons that i am interested in...
Ok,
The text of the buttons are in french for me.
thanks Yves :U
i see that PlaySound will also play a few of the system sounds by way of ID using SND_ALIAS_ID
;SND_ALIAS_SYSTEMEXCLAMATION SystemExclamation
;SND_ALIAS_SYSTEMASTERISK SystemAsterisk
;SND_ALIAS_SYSTEMQUESTION SystemQuestion
;SND_ALIAS_SYSTEMDEFAULT SystemDefault
;SND_ALIAS_SYSTEMEXIT SystemExit
;SND_ALIAS_SYSTEMHAND SystemHand
;SND_ALIAS_SYSTEMSTART SystemStart
;SND_ALIAS_SYSTEMWELCOME SystemWelcome
Hi Dave,
Here is another thread :
http://www.masm32.com/board/index.php?topic=7375.0
thanks Erol
that looks similar to mine
we must have used the same guy as reference :P
i am trying to learn some of the finer points about MessageBoxIndirect
making kind of a "super MB wrapper"
ok - another question :bg
MessageBoxIndirect - MSGBOXPARAMS Structure
lpszIcon - LPCTSTR
Identifies an icon resource. This parameter can be either a null-terminated
string or an integer resource identifier passed to the MAKEINTRESOURCE macro.
i am trying to figure out how a "string" might identify an icon, other than if it were a file name
...Assume that I'm totally WRONG about this,...but,...
The LPCTSTR type in C++ is just a pointer to a string constant. In assembly, you can ignore the constant, and, yes,...it's the address of the file name. Using the MAKEINTRESOURCE macro is easier,...you just provide the assigned identifier from your resource file. What i don't know is,...can you INVOKE a C++ language macro from your assembly langusge program ???
If you read: LoadIcon Function (http://msdn.microsoft.com/en-us/library/ms648072(v=vs.85).aspx), there is a list of predefined system icons and their ID values.
oh yah - i am aware of the standard icons
MAKEINTRESOURCE is totally a C thing - not necessary in ASM
in C, all it does is cast a 16-bit integer as a 32-bit integer
i am just trying to make a flexible message box routine
i am combining the custom buttons in the original post with MessageBoxIndirect
put the whole thing in a wrapper and make it as easy to use as is practical :lol
i still have a few wrinkles to work out, but....
(http://img13.imageshack.us/img13/1235/test1hr.png)
If I click the possibly button, what happens?
it's an old design paradigm of mine i like to call "maybe logic"
maybe it will......
....but then again, maybe it won't :bg
"possibly" just shifts the odds a little
(which pretty much describes how well my little routine is working)
:bg
Dve,
This exercise in tweaking a system message box must be being done for amusement or perhaps academia, here is a quick scruffy 4 button dialog that coded up in a few minutes.
....and it didn't work
:bg
i had to add InitCommonControls
but - that is a lot of code for 1 box
the routine i am writing can be used over and over in the same program to make several types of boxes
that is the real advantage of using MessageBox or MessageBoxIndirect
the system does a lot of the work for you
p.s. i didn't think you were old enough to remember Greta Garbo :P
back in the day, i always had a thing for Gene Tierney and June Allyson
i suppose, if you learned your way around the templates, you could do something similar with dialog boxes
you could write a routine that builds the template on the stack
and let the user create a small structure to define the outine and point to button strings
pass that to a function and let it make the box
the buttons could have the same ID every time - like messagebox
no need for more than 4 buttons - usually 3 is plenty
i must admit, the messagebox functions give you some stuff that isn't very usable in a generic way :P
Funny enough I originally had "InitCommonControls()" but it worked without it so I removed it.
i think a good rue of thumb is - if you have a manifest, it needs it
:bg
(http://img31.imageshack.us/img31/4906/mbhp.png)
Quote from: hutch-- on August 19, 2011, 05:02:43 AM
Funny enough I originally had "InitCommonControls()" but it worked without it so I removed it.
I had to add it, too. Without it, the code assembles and links fine, it runs but even a call to a simple MsgBox does not show anything.
start:
print "I am a console app", 13, 10
invoke MessageBox, 0, str$(eax), chr$("Result"), MB_OK
print "... and there should have been a MsgBox", 13, 10
Text comes over clearly, provided you used console assembly, but no MsgBox...
If, however, you comment out the manifest in rsrc.rc...
//1 24 "manifest.xml"
... it works like a charm even without InitCommonControls. So Dave is absolutely right :U
What fascinates me with this variation is I use a normal installation of a US edition of XP SP3 with no MS updates and it runs everything. Same with my Win7 64 bit. The 2 editions are respectively XP SP3 Professional and Win7 64 bit Ultimate edition.
I used to routinely enable all common controls but Erol found that his Turkish version would not run if they were all enabled but not used.
the ms updates must be the difference
i have a pretty complete set of them on this machine, up to dotNOT 4.0, which gives XP MCE fits
QuoteErol found that his Turkish version would not run if they were all enabled but not used.
makes you wonder how they knew which ones you were going to use - lol
it must be that some just plain did not work correctly on that machine
See if this one works, it ony enables the win95 controls.
first time :bg
ICC_WIN95_CLASSES includes a lot of stuff
it would probably be more correct to say...
if your manifest file specifies a version of CommonControls, the program should include InitCommonControls/Ex
ok - question, Hutch
in the resource file for the "multibutton" example you posted earlier...
100 DIALOGEX 327,117,334,88
CAPTION " Make A Decision"
FONT 8,"MS Shell Dlg",0,0,0
STYLE WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|DS_CENTER|DS_MODALFRAME
BEGIN
CONTROL "Yes",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,86,62,56,14
CONTROL "No",IDC_BTN2,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,146,62,56,14
CONTROL "Who Cares",IDC_BTN3,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,206,62,56,14
CONTROL "Outa Here",IDC_BTN4,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,266,62,56,14
CONTROL "",IDC_IMG1,"Static",WS_CHILDWINDOW|WS_VISIBLE|SS_CENTERIMAGE|SS_ICON,14,12,64,64
CONTROL "IDC_STC",IDC_STC1,"Static",WS_CHILDWINDOW|WS_VISIBLE,88,12,232,44
END
not sure i understand that last one
i do not see IDC_STC or IDC_STC1 referenced anywhere in the asm source
is that how you position the "message" text ?
seems like a lot of overhead for ms to create a control to put text in there - lol
ok - i did find it in the asm source as "106" - hLabel
He references it by number in code - 106
case WM_INITDIALOG
m2m hWnd, hWin ; Copy hWin to GLOBAL variable
invoke SendMessage,hWin,WM_SETICON,1,FUNC(LoadIcon,hInstance,500)
; --------------------------------
; Get the handle for each control
; --------------------------------
mov hButn1, rv(GetDlgItem,hWin,101)
mov hButn2, rv(GetDlgItem,hWin,102)
mov hButn3, rv(GetDlgItem,hWin,103)
mov hButn4, rv(GetDlgItem,hWin,104)
mov hImage, rv(GetDlgItem,hWin,105)
mov hLabel, rv(GetDlgItem,hWin,106)
thanks Rob :U
Dave,
Its mainly a difference in how Ketil's resedit handles ID numbers. I have never used equates where resedit does not appear to have an option to directly work in ID numbers and always generates equates for each control.
got it :bg
well - i finally got a box with a button using DialogBoxIndirect :lol
i must say that, of all the ms stuff i have seen, the template structures and arrays are the poorest in terms of organization
i am still a n00b, though - i am sure i will find something worse, eventually
on the plus side, it is easy to get a handle and examine the class structure members of example items
a good example is the button "shading" or "raised" effect
i can poke around in the guts of windows a little bit and see how they do it :bg
Dave,
Give this script a blast, it writes a simple dialog then starts the project in a new QE window.
:U
i am kinda new to dialogs - lol
thanks Hutch
apparently, the gradient fill button is not a style or extended style
i guess it must be paiinted in
i saw someplace that it is supported with CommonControls 6.0 or better - what a coincidence :P
ohhhhhh
you have to have a manifest file to get the gradient fill :U
Dave,
Here is another approach to creating a 3 button dialog that has user text control. The test piece is a normal resource dialog but the 3 button dialog is coded in memory and does not need a resource section so it can be put into a library module.
thanks Hutch
that is a little more like what i am after
my current game plan is to create the box and buttons in the MsgBoxEx function
also, the function will play an optional sound and set the small icon in the title bar, if any
the hardest part of the whole thing will be figuring out sizes - lol
then, in the DlgProc, set all the text, similar to what you are doing
except this one has no resource file data at all
i haven't decided whether to set the large icon in the DlgProc or the function
i am using DialogBoxIndirectParam, and passing the address of a list of text pointers
the code is very small :bg
and, now that i have a manifest file, i have the gradient buttons :8)
here is a simple box with a button
;button
push 0
push 80h
push IDB_BTN1 or 0FFFF0000h
push 0E0049h ;size = 73 x 14
push 170009h ;pos = 9,23
push 0 ;extended style
push WS_CHILD or WS_VISIBLE or WS_TABSTOP ;BS_CENTER ;BS_PUSHLIKE ;BS_PUSHBUTTON
;dialog box
push 0
push 32h ;height = 50
push 640000h ;width = 100, y = DS_CENTER
push 1 ;x = DS_CENTER, cdit = 1
push 0 ;extended style
push WS_POPUP or WS_CAPTION or WS_SYSMENU or DS_CENTER or DS_MODALFRAME ;WS_OVERLAPPED
mov edx,esp
INVOKE DialogBoxIndirectParam,hInstance,edx,edi,DlgProc,edi
add esp,52
the MsgBoxEx function will be based on that code
as i said, much of the code will be dedicated to figuring out how big to make everything
pixels aren't pixels, anymore - lol
everything is in "dialog template units" ::)
as a maximum, i will give them:
optional/selectable sound
small icon in the title bar
large icon in the message area
a check box
up to 4 buttons
text in the title bar, message area, check box, and buttons
the form will be:
INVOKE MsgBoxEx,hWndOwner,lpszMessage,lpszCaption,lpStructure
there will be options, like selecting the default button, EscapeKey/Close alias, and so on
The thing that makes message box replacements fun is the requirement to auto size the text display area to fit the size of the text, it means measuring the size of the provided message text and sizing both the dialog and the text display area to fit that text. It can be done but its no real joy to code.
Depending on how you create the basic window, it does not matter if you work in pixels or dialog units but if you are going to start resizing windows you will probably have to work in pixels.
that is the hard part
in many ways, i want to mock the behaviour of MessageBox
some of it is pretty simple - some, not so much
i can use 1 of 2 approaches to get there
1) experiment with MessageBox and chart it's behaviour
2) disassemble MessageBox and mimic their sizing code
the later is probably more effort than i want to put in - lol
i can start with an enormous chunk of text and see what happens
the icon placement is straightforward
the button placement follows a simple rule, after message text is placed
button size is always the same, although the MessageBox function has a limited number of strings
i plan to expand this a little, so that the MessageBox sized button is the minimum,
but longer strings get a longer button - that is probably the only thing i want to change
i had thought of "auto-formatting" message text
i.e., if a large message string has no line-feeds, i could keep the box at a certain aspect ratio
we'll see how cold the water is when i get to that bridge :P
Hutch,
i did run across this handy little function that you might like...
SendDlgItemMessage
you don't have to retrieve and store all the control handles
you can send messages to the controls by referencing the dialog box handle and the control ID :U
http://msdn.microsoft.com/en-us/library/ms645515%28v=VS.85%29.aspx
i see that MS was careful to leave me room for improvements :lol
(click on image for full-size)
(http://img801.imageshack.us/img801/9940/mbtst1.png) (http://img801.imageshack.us/img801/9940/mbtst1.png)
Dave,
SendDlgItemMessage() works OK but it does nothing better than GetDlgItem() placed in the handle position in SendMessage(). In a simple dialog you can use either to deal with the handles but with anything much more complex its worth the extra typing to get the handles for each control as you then have no effective limit on what you can do with them.
ok - ran across a little bug
i want to see if it is specific to my machine, or a general XP bug :bg
what's wrong with this picture...
(http://img707.imageshack.us/img707/6615/mbtst2.png)
attached is a test program that creates 8 boxes
when all 8 are closed, the program exits
you may have to try it a few times - i get different results each time
after running it a few times, i get all good buttons - lol
it may be that i am running them in threads and MessageBox does not like making so many at once
Dave,
About the only difference I can see from running it is the message boxes with the icon are slightly taller as an icon is higher that a single line of text.
thanks Hutch
it is the buttons
if you look at the pic above, one button did not get the uxtheme gradient fill ::)
Dave,
Not here and that is after 4 tries. All button have XP appearance.
Gradient fills are scary stuff, especially in screenshots, it is a hacking feature :naughty:
Hi,
Windows 2000 the standard flat look. Windows XP, two
CLI starts both, had one "bad" button. Two double-click starts,
one all good, one had three off buttons.
Cheers?,
Steve
thanks for testing, guys :U
the solution seems to be to put a little delay between thread creations
i re-wrote this one to be a little slower, too :P
Dedndave, custom message boxes can become very fancy, nice little clicky buttons, shiny, quick and fast (With a little magic), but in the end of the day, the transformation from the default windows look to a more customized look, the blend will corrupt the quality of it, despite how nice the message box will look, the quality will become corrupted (magically) and the only way to undo the damage is to customize the entire application, you should switch focus to where it is really needed :U
there is nothing "custom" about it, really
the gradient button is part of the XP uxtheme upgrade :U
if you have a manifest file and specify Common Controls version 6.0 or higher, you get the gradient buttons
(http://img846.imageshack.us/img846/7342/uxtheme.png)
If it separates too much from the general preference or native look or parts of your own program it may be wise to switch focus.
MessageBox's are modal dialog boxes
normally, they get the focus automatically
for the test, i placed the MessageBox calls in seperate threads
threading them like that has the effect of making them modeless
actually, i just wanted to make a picture with several different boxes at once so i could measure pixels :P
i am too lazy to modify the program 8 times and copy/paste the pictures together - lol
Sounds good. I accept your idea.
For focus, use MB_TOPMOST,MB_TASKMODAL and MB_SETFOREGROUND
That will make sure it doesn't get hidden behind whatever window handle you feed or don't feed messagebox.
ahhhhhhhhh.....
DS_USEPIXELS
:8)
well, it sounded good - lol
here's a fun little toy...
(http://img851.imageshack.us/img851/5585/mbctrl.png)
Dave,
Here is a variation on the earlier demo, instead of using a static control, I have used an edit control set to read only which matches the colour of the static but has a scroll bar for text that will not fit into a small viewing area.
i like it :U
something along that line came to mind when i noticed the SS_EDITCONTROL bit was set in their text static
not sure why they set that bit - it must have to do with how text is formatted
at any rate, providing a scroll bar is probably easier than figuring out how to jam big text in a small hole
i have learned a lot about dialog boxes by playing with this thing
and, i have really only touched on scroll bars, edit controls, buttons, and, now, statics
that is only a small part of the list and i am still a novice in those limited areas - lol (all the easy ones)
and they think i want to learn a new API ::)
ok - new question :bg
is there a magical formula that tells us the "lead" and line-spacing used in static text controls ?
or do we just wing it ?
(http://img683.imageshack.us/img683/2817/dlgtext.png)
EDIT:
i am using the SS_EDITCONTROL style bit
maybe i can find something in the documentation for edit controls...
GetTextExtentPoint32 gets me a string height - maybe i can work with that...
found it...
GetTextMetrics
thanks, guys :P
Dave,
A normal edit control does the job for just plonking text into a control but if you want more formatting options, use a rich edit 2 or later control, you can easily control many more things.
it's not "what i can do" with the control that i am trying to learn :bg
i am figuring out how text of different fonts is rendered in a static control
i have to know how it works in order to take a specified string and know how large to make the static
i have a pretty good "handle" on it, now
it always comes down to messing with fonts - lol - hate the damn things
there is too much stuff to know that i didn't want to know about :bg
simply put...
the caller gives me a string
the OS gives me a font and pitch
i have to figure out what dimensions are required for the static control :P
(and, if it's a long string, how to break it up into lines)
part of my learning process
i think it's a bug that the larger font returns true for Italics when it is not
if it really were an italic font, the overhang would be non-zero
(http://www.masm32.com/board/index.php?action=dlattach;topic=17254.0;id=9678)
the attached file is the above PNG image renamed to ZIP