Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / How to prevent dialog boxes from wiping out the main window?

Author
Message
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 9th Apr 2008 23:07
Hello,

When making dialog boxes using the win32 api, I noticed that if you drag them around, it erases what is behind them on the main window in DBC. Is there a way to prevent this, or redraw the window when the dialog box is moved?

Here is an example using a message box. Drag it around and the space behind it will be black.



Enjoy your day.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 10th Apr 2008 18:00
hmm...
don't have a pc to test
sounds like db isn't getting refreshed
have you tried that command that keeps a window active?
ALWAYS ACTIVE ON i think

jinzai
17
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 10th Apr 2008 18:42
The quick answer is that you can't. You need a modeless dialog to get that to work, and I am not seeing any modeless dialogs being used in DBC, or DBPro. MessageBox is one of the dialogs that are totally modal. There is no way to make MessageBox modeless.

The thing is that DBC, or DBPro, or whatever is calling the dialog procedure gives up control to the dialog box. That is why they are called modal, your application is essentially asleep while it is active.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 10th Apr 2008 19:28
Thanks jinzai.

So then why in a non-DBC app does the window behind the message box redraw? If I put the message box code into a DLL, would there be a way to call it so that DBC's window refreshes? I tested it by calling it from inside a custom DLL but it still overwrites the window.

Enjoy your day.
jinzai
17
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 10th Apr 2008 19:49 Edited at: 10th Apr 2008 19:57
The other applications use the standard Windows paint method, and DX does not...it uses Render instead, and only emulates standard Windows GDI.

It will always do that because MessageBox is modal. You can make a modeless dialog in a DLL by creating the dialog resource, and instead of calling DoModal, calling CreateDialogIndirect. I think you'd really have something then. People would really like that! Actually, hold on...I think I have an example of that.

I once replaced the FileOpen common dialog that way, but now it is more complicated. I have not gotten around to doing it again in 32-bit Windows, as the method is different from before. (I was able to import the dialog, and edit it then. Now, you have to edit the common dialog resource directly.)

EDIT: My code uses CreateDialog. CreateDialogIndirect is for templates in memory...sorry about that. Anyway, you can use CreateDialog, but then you need to use handlers for the buttons, and destroy the dialog yourself. Its not terribly difficult, but you will have to handle the messages in the normal message handler by either hooking the DB windows' wndproc, or using PeekMessage.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 10th Apr 2008 20:16 Edited at: 10th Apr 2008 20:24
@Obese
Oops! I missed your response.
Quote: "have you tried that command that keeps a window active?
ALWAYS ACTIVE ON i think"


I thought that might be the case too so I tried it both OFF and ON, but control wasn't released back to DBC

@jinzai
Thanks again jinzai. CreateDialog will probably be the next step - though I've only ever used the common dialogs that are nice and neat and premade!

What about calling the message box from a different thread or process? I made the message box run as an exe and called it from DBC using EXECUTE FILE. It runs as it's own "thing" and therefore doesn't overwrite DBC (in fact DBC will just keep on going in the background. Of course problems arise - if, I close the DBC window, the message box remains if I haven't chosen an option... Is there some way I could check IsWindow and force the message box to close if the DBC window disappears?

If I could call it from a DLL instead of an exe, how could I run it as it's own process so it behaves similarly to how it runs as an exe? Then maybe I could check DLL_PROCESS_DETACH and use EndDialog or something to close the message box if the DBC window closes before the message box? Just trying to brainstorm a bit... (and avoid having to make my own dialog box )

Enjoy your day.
jinzai
17
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 10th Apr 2008 21:09 Edited at: 11th Apr 2008 03:18
Then you will have to get into interprocess communication, and stuff like that. Perhaps the cure is worse than the ailment in that case...idunno, that's your call, obviously.

Here is the source for the DLL that I'm attaching. All it contains is the jzModelessMessageBox function. It's not the best, just a quick and dirty version of what I am talking about. The thing leaves a trail on my machine, but I think that is not an issue with all machines. At any rate, it will repaint when you are done moving, which is what you want, isn't it?



EDIT: I have been experimenting with the best settings for this, and also...mine trails because I have draw window contents while dragging enabled. When I disable that, it works as expected. Also, are you using a compiler that has a resource editor? If not, I can give you a couple of files that will be quite useful for this, and will allow you to make dialog templates much easier.

Attachments

Login to view attachments
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 11th Apr 2008 19:53
Thank you.

Seems interesting. I'll have to try it out. How should I call the functions in your DLL from Dark Basic?

Quote: "Also, are you using a compiler that has a resource editor? If not, I can give you a couple of files that will be quite useful for this, and will allow you to make dialog templates much easier."


I don't think so. Those files probably would come in handy! Thanks again.

Enjoy your day.
jinzai
17
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 11th Apr 2008 23:16
The only one you can call directly is jzModelessMessageBox, like so:

integer = jzModelessMessageBox("Text to display", "TitleText", 0)

The last parameter would be analogous to the flags used in MessageBox, but....the simple dialog template I cobbled up is really basic, and only has the OK button.

The dialog in that DLL is the earliest version, and you will still have to alt-tab to get back to your DB app, and the dialog will disappear, but remain open until you dismiss it. That dialog will only be on top when it has the focus (It owns the keyboard.) My latest version works a little differently...it will stay on top.

I have some more ideas, you've opened up a quite broad topic, imo.

Very well...I think that we should develop a plug-in that will allow users to provide a text file that describes a dialog that they want, and then be able to use that dialog in the modeless...mode. This text file will have the same format as the resource complier input file (Those with the extension .rc).

I will get you a basic version of what I am talking about...hopefully by Monday. Right now, I am working on several projects. (This is a common area to most of them, however.)
TDK
Retired Moderator
21
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 14th Apr 2008 07:17
A quick and dirty method which might work (if all else fails) is to use Get Image when the dialogue is on the screen then place the actual dialogue off screen.

You then drag the image around the screen, deleting it when the mouse button is released - placing the actual dialog in the position the image was dropped.

Worth trying if you don't have any other choice.

TDK_Man

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 14th Apr 2008 10:59 Edited at: 14th Apr 2008 22:40
@TDK
[EDIT]
I'm not sure what you mean. I'm not sure if a messagebox would let me do anything but drag it or click on one of it's buttons - I had an idea about going in this direction (if you are suggesting using the DBC commands to capture the image)

Ok, I've found a solution and it is most similar to what TDK was saying. I was actually trying to do something similar but I was thinking too big. I think the solution I was thinking of that may be too big would still be effective and could be applied so I'll mention it for the more ambitious (I tested it out in C and it works). Basically, you create and register your own window class which will end up being a child window that appears in front of the DBC window that is the same size. In the WNDCLASS structure, you set the background to a snap shot of the DBC window (which you can get through various means using GDI and DCs or virtual keypresses of printscrn). Then you call your new window as a child window of the DBC app, and then call the standard message box or any other common dialog (open file, page setup, color select - etc) The new dialog can be dragged around and it won't obscure the child window background. Retrieve the button click from the message box or other dialog, and then close or destroy the child window.

Now the solution I'm planning on implementing: After trying the above method, I wanted to scale things down and just use commands straight from DBC without having to write a custom C DLL or exe.

So using the same premise, I get a screen capture of the DBC window. Now I want to replace the background of the DBC window itself (with itself basically). The default background for it's class is black. So when I move a modal dialog around, the rendered background (what we see when we send commands to DarkBASIC) get's replaced with the true background. I have to change that to the screen capture so we see the window itself as the background. So, I have to grab the bitmap from the clipboard (GetClipboardData()) or from a GDI DC client rectangle, convert it to a brush (CreatePatternBrush()), and then replace the class entry in the WNDCLASS structure for the DB window. All I need is the HWND for the DBC window (a few different functions for that - easy one GetActiveWindow() ) and a call to SetClassLong() with GCL_HBRBACKGROUND as the index and my new brush as the background. This can all be done right from DBC using calls to the win32 API without having to write a custom DLL.

This can also be used to set a permanent background for your DBC applications without additional redrawing overhead - possibly. Can be pretty handy!

Now I just have to test what happens with CLS and if there are any problems with the backbuffer or anything similar. I may have to get the original brush that was used to paint DBC and then set it back after the modal dialog box calls.

Enjoy your day.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 19th Apr 2008 17:26
curious...
if you set INK 0,255 does it wipe out blue?

It is far better to complete a 10 line program than to start a 10,000 line program.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 26th Apr 2008 11:12
Interesting idea. I think the text background is created before it is blitted or rendered to the screen and the text with it's background are painted all at once. It's not really the background of the window per se. Unfortunately it doesn't change the behavior of the message box though.

Enjoy your day.
jinzai
17
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 26th Apr 2008 11:48
Yes, that's all very true. You will also continue to come back to this deal about modal vs. modeless. Its sort of a fundamental thing about Windows that the best way around is using modeless dialogs.

The trouble is...that you then have taken on quite a bit of responsibility. That is why I made that little modeless message box in the first place.

It is also why you see such a proliferation of GUIs for DBC/DBP/GDK. The ones for GDK make the least sense to me personally, since you are already developing in the same environment/context that all of these products are created in...with all of the Windows GUI there already. Windows is a GUI, after all.

Unfortunately, most people come here because they want to write games, not Windows apps, so the learning of the Windows GUI seems to get in the way. That's too bad, because all the answers to these types of issues are contained in Windows already.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 26th Apr 2008 11:54
Thanks Jinzai.

Changing the wndclass of the DBC window by adding my own background seems to do the trick for being able to use the model dialog boxes. Let's me use that functionality that's already built into windows.

Enjoy your day.

Login to post a reply

Server time is: 2024-03-28 08:39:15
Your offset time is: 2024-03-28 08:39:15