C++ Modal dialog box continuing adding texts - c++

I have dialog box and in it, it has OK and Cancel buttons then it also has a ListBox to display text in two columns. I would like to continue adding text into the ListBox after the dialog box is shown. How can I do that? Because after I call DoModal() to show the dialog box, the code does not continue to execute. Or should I create two threads (one is display dialog box while another thread continues adding text to dialog box)?

Make your dialog 'pull' the data it needs, maybe polling the data source with window messages every second, or every 100ms or so. Or, if you go the 'two threads' route (the better but more complicated option), have your data source post a window message to your dialog when there is new data, and then have the dialog fetch the data it needs. The reason for this is that it's much easier to use the existing CDialog infrastructure to get a window that behaves like an actual dialog, compared to building a modal window that acts like a dialog but isn't really.
If you do go the two threads route, your division of labor should be: one thread that does all the UI work (including showing the dialog), and one that 'generates' data and lets the UI know when there is new data. So the worker thread should not do anything related to the UI, nor call any methods on the dialog directly - you can't access windows from several threads. The only cross-thread window communication should happen through window message (i.e., use ::SendMessage()). So certainly don't do something like myDialog->m_theList.AddString("blah") from another thread, or something like it.

Showing a dialog box modally halts further execution until you close the box. Instead of showing it modal, show it normal but make it always on top so you can continue executing the code after the call to DoModal(). Alternatively, populate the box with all the info it will need before you call DoModal().

If you decide to take the "two threads" approach you will discover that the controls on MFC dialogs should not be updated or accessed from a thread other than the one that created the dialog. Even if you have pointers to these controls available in another thread it is not thread-safe to access them. This rule applies whether or not the dialog is modal.
Instead, your second thread would need to PostMessage or SendMessage to the dialog window, so the updates occur on the thread that created the dialog (most likely the main UI thread of the application).

Related

How do you code merging different executables into a single window frame? Like browsers do?

OK, so a noob question here: How do you code this functionality that browsers have for example? You open a chrome browser for example and you can open multiple tabs open. Then you can move one tab out of the window and it becomes another window, having its own separate process. Then you can drag that tab into another window and they become one frame? Similar to docking in windows applications, but how do you do it with executables?
Windows-specific answer, though I think other OSs work pretty much the same: the HWND handle that you get for a window is global. If you send its numeric value to a different process, that process can use it to do things with the window: get its information, resize it, even draw on it. What it can't do is replace its event handler function.
To get process separation like browsers have nowadays, the key is to create a container window and send the handle to the child. The child then creates its own window as a child of the container. The child window simply fills out the entire content area of the container.
This way, the content process is contained within the parent's window, but can handle events.
Now, if you want to drag out a tab into its own top-level window, the parent process creates a new top-level window with all the UI inside, and then re-parents the content container to this new top-level window. The content child follows along.
I can't tell you how to code it, you should search the feature inside the chromium code to know how it's coded but I can tell you how it works:
Inside chromium every tab, extension, utility, etc is a process, each one of these processes is child of the "Browser" process, the "Browser" process manages everything (creating new windows, opening new tabs, closing tabs, destroying windows etc) so, for example, whenever you open a new instance of chromium you are telling the "Browser" process to create a new tab and put it inside a new window.
Every window is managed by the "Browser" process and every tab is managed by a process that is child of the main process.
Now to reply your question: when you drag & drop a tab outside a window you're triggering an event that is caught by the "Browser" process which then create a new window and assign the tab to the new window.
Those informations should give you a hint on how you could develop this feature yourself.
If you want to know more about the chromium architecture I suggest you to read how chromium is designed at https://www.chromium.org/developers/design-documents

Display and use the same MFC CList control in multiple dialogs

I am coding a test application for a windows CE device. This is the first time I am programming for a handheld device. I use MFC VC++ on Visual Studio 2008. I have found that there are many restrictions in the controls and what I could do with them when running the program on a handy versus when I run a similar program on a desktop computer.
Now, the device I am currently deploying my test program to, does not have a touchscreen and has few extra keys other that the numberpad 0-9 keys. So, I have to do with a simple GUI that uses keydowns to call specific functions like add, edit, delete etc... It also forces me to use separate dialogs for each of these functions so as to avoid unnecessary mouse cursor usage.
This leads me to my current problem: The 'ADD' dialog of my test app adds some user data to a CListCtrl that is on the 'MAIN' dialog. The 'EDIT/DELETE' dialog is to allow the user to select the desired data from its own CListCtrl and press the "ENTER" key, which thereby deletes the selected data from the 'MAIN' dialog's CListCtrl. Thus, both the main dialog and the 'EDIT/DELETE' dialog have CListCtrl with the exact same data. So, instead of having to use 2 separate list controls and using loops to copy the data to and fro among them, is there a way in which i could use the exact same CListCtrl (one and only one instance of the CListCtrl exists), but display it on 2 separate dialogs? This would remove all the copying code, as well as halve the amount of data in memory.
I tried passing a pointer to the MAIN dialog's CListCtrl to the 'EDIT/DELETE' dialog in hopes that I could redraw the control there, but in vain. I could call the RedrawWindow, RedrawItems commands, but they seem to have no effect in the 'EDIT/DELETE' dialog (I think it is because the control itself is not present on the edit/delete dialog). Any other suggestions?
You could temporarily change the parent of the ListCtrl using CWnd::SetParent to the EDIT/DELETE dialog, and set the position with CWnd::SetWindowPos to where you want to have it. When the dialog gets closed, set the parent back to the MAIN dialog.

Programmatically clicking toolbar button in parent of modal window

I have an application that hooks into another application via an API. My application launches a modal window which prevents keypresses to reach the parent as one would expect.
However due to limitations in the API I need to click one of the parents toolbar buttons from time to time (yes it's a kludge).
I wonder if this is possible while still having the modal window of my application active? Is it perhaps possible to send the required command directly into the parent command queue?
Clicking the button programmatically with no modal window should not be a problem, one could go by this link for example: http://forums.codeguru.com/showthread.php?307633-How-to-run-a-very-long-SQL-statement. But I would prefer not having to close my window each time I have to click the button.
Although the fifth answer is what I find interesting as I'm thinking this could make it possible to send the command without having to close my modal window first. Also it feels an ever so small bit less ugly.
First of all, when a modal dialog is shown, it runs its own message pump. So any attempt to fake input messages will land in the modal dialog message pump. Which is no good to you. So, you'd have to send a message rather than fake input.
However, when a modal dialog is shown, its owning windows are disabled. Which means that these windows will not respond to any messages you send. So I guess that means that you could:
Enable the owning top-level window that you hosts the toolbar in question.
Send the message to the toolbar button.
Disable the owning window again.
Not the prettiest way to go about things, but you did ask!

A blocking but non-modal QDialog?

I have a stack of images on which I want to perform some operations. After processing each image, my program should pop up a dialog to prompt the user if they want to proceed with the next image or to abort. Before that, they should have an opportunity to do some manual changes either on the images or on the parameters. Anyway, they must have access to the windows of the applications, while the execution of the method that called the dialog should be blocked until the dialog is closed.
I tried to solve this with a QMessageBox, but if I open it via exec(), it blocks the entire application, and if I use show(), the execution of the program goes on without waiting for user's reaction.
Is there a convenient way to block the calling method or function with a dialog but permit the user to interact with other windows?
Thanks in advance for any hint.
You should split your method that you want to block into two parts. In the end of first part you need to show your dialog without blocking and connect "Next" button (for example) of the dialog to the slot that must contains second part of your old method. This slot will be executed only when user presses the button.
It's the right way to do it in Qt. You need posibly to change your code logic to implement this.
Also, do you really need the second dialog? You can place "Next" button to your main widget. You can also create another modal dialog that will contain some settings and "Next" button.

win32 DialogBox app: how to show text from callback on the DialogBox?

I'm working on a win32 DialogBox based app. This uses DialogBox() to create the dialog box, and has a dialog box procedure which does all the usual things.
The dialog box has some static text controls on it, and generally I'm showing text in these via SendDlgItemMessage() from within the dialog box procedure.
However at one point the DialogBox initiates a lengthy operation. This operation has a callback with a series of status messages. I'm having some trouble showing these messages on the dialog box, for two reasons:
The callback function doesn't know what the dialog box HWND is, because it gets called from the code which carries out the lengthy operation. I suppose I can define a file scope HWND variable and copy the dialog box HWND into it from the dialog box procedure just before the lengthy operation is started. That way, the callback function could have access to the dialog box HWND. But that seems awfully kludgy: is there a more elegant way?
The dialog box procedure is blocked while the lengthy operation happens. This doesn't matter because it's an embedded system. But will Windows even show the text in the dialog box if I issue a SendDlgItemMessage() while the dialog box procedure is blocked?
edit I've done some investigations using SendDlgItemMessage() to send a WM_SETTEXT to a static text control on a dialog. The text is displayed immediately even if the dialog box procedure is blocked.
Well, your dialog HWND is a singleton so it isn't the end of the world. But yes, the standard way this is done is by passing an opaque pointer to the code that gets the job done. Compare with the lParam argument of EnumWindows() for example, the callback gets that pointer back.
Whether a control repaints itself immediately is an implementation detail. I only know of progress bar doing this. You could call UpdateWindow on the dialog window handle to get any pending paint updates flushed to the screen.
The all-around better mouse trap is to perform long running tasks on a worker thread. Avoids Windows displaying the "Not Responding" ghost window, avoids timeouts on broadcast messages and numerous potential deadlock problems. But tends to be tricky to get right, you cannot update the window directly from the worker thread.