How to reuse the same window after refreshing in the REPL? - clojure

In a source file called gui.clj, I define a frame, fr, that holds the window for my application, like this:
(def fr (frame ...))
and a run function that sets up fr and causes it to repaint when data changes, something like this (modeled on scribble.clj:
(defn run []
(-> fr add-behaviors pack! show!)
(when-data-changes
(swap! state assoc :shapes (dot/g->seesaw t/ws))
(repaint! fr)))
As I'm messing around in the REPL, I often modify a source file and then call c.t.n.repl/refresh. When I run run again, it puts up a new window, leaving the old window on the screen. How can I make my (newly updated) code operate on the same window even after a refresh?

You can put your application's state (containing the window object) into a defonce in a separate namespace and call disable-reload on the namespace. This will prevent the reloading of the namespace when (refresh) is called thus keeping the original state (containing the original window object).
In practice, however, it is usually better to clean up and restart the application on reloads. It can be dangerous to hold to obsolete objects from the previous state of some namespace. Use component or mount to manage the application state.

It sounds like you want to have a bit of a "lifecycle" for the stateful parts of your program, somewhat like
make it exist if it does not
let it run
clean it up
and would like this to happen when you reload. You can have the same window continue to exist and get new contents by adding code to your clean-it-up function that clears the window, or you can close the window and create a new one for each cycle.
I have used the component library for larger projects using this style and it was very effective, though it's a bit of a lifestyle change to get used to it.
for your case you may just want to initialize an atom fro store the active window then define the three basic lifecycle functions that opperate on that atom's contents. (and put the actual atom in a defonce)

Related

How to programmatically print without prompting for filename in MFC and CView using Print-To-PDF printer?

I have a large graphics program using C++, MFC, and C++6.0.
I need it to print to PDFs without prompting the user for printer settings and file name.
I use CView::OnPrint() to print using Microsoft Print-to-PDF and it works fine except for the user prompts.
I've seen how to bypass those prompts with a PrintDocument object in C# but how can I do that when using CView::OnPrint() in MFC? Surely there must be a way?
My project is much too big to consider re-writing in C#, and I've tried moving forward to Visual studio 2005/2010/2019 etc. without success as changes in default data structure packing and converting existing data files is fraught with problems so solution has to be an addition to existing MFC C++6.0 if at all possible.
Can anybody help?
I haven't used VC++ 6 in quite a while now, so I'm going from rather distant memories, but the general idea is fairly simple.
Full Approach
Your view has a DoPreparePrinting member function. By default, this creates a CPrintDialog object, then invokes the CPrintDialog's DoModal to show the print settings dialog. Eventually (but not in DoPreparePrinting, if memory serves) that CPrinterDialog's CreatePrinterDC will be called to (obviously enough) create a DC for the printer using the settings the user entered in the dialog.
To bypass the dialog, you can override DoPreparePrinting. That receives a pointer to a CPrintDialog. Since you don't want to show a print dialog, you obviously won't invoke its DoModal member. Instead, you'll fill in its DEVMODE and DEVNAMES structures for the printer and any settings you want. Then when CreatePrinterDC gets called, it'll use what you filled in without displaying the dialog.
My personal advice would be to do a run using the dialog under the debugger, then after the CPrintDialog's DoModal has returned, look through the DEVNAMES structure it returned. You may not need it, but I found the DEVNAMES structure a little confusing the first time I had to set it up on my own. The DEVMODE is bigger and arguably more complex, but I've usually just modified a few bits and pieces, and left most of it with default values.
Simplified Approach
If you just want to use the system's default print settings, there's a simpler approach: you can override OnPreparePrinting. This receives a pInfo parameter, which is a pointer to a CPrintInfo. That has an m_bDirect member, which you can set to true to do "direct" printing, which just uses the default settings without using a printer dialog. I don't remember for sure when m_bDirect was added though. If it's missing, there's a "trick" to get the same effect: the default implementation of DoPreparePrinting doesn't display a print dialog for a print preview, so you override OnPreparePrinting to set m_bPreview to true, invoke DoPreparePrinting, then set m_bPreview back to false.

Qt/QML: Delay window rendering until data is available

I am building an application using Qt/QML. The QML of my main window is very complex and depends on lots of data which must be loaded via HTTP and then be processed by a C++ backend before it is ready to be displayed.
The C++ backend provides a signal which is fired when the data is ready. Until then, I want the window to be empty except for a simple loading indicator being displayed. Of course, I could use a simple overlay which hides my actual interface until the data is available, but this would mean that the QML code of my actual user interface is already loaded and tries to access the not-yet-available data, which is causing a lot of errors, so I would need to add dozens of dummy values and NOTIFY signals for each single property which might not yet be available.
What is the best way to completely deactivate a portion of QML code and to enable it as soon as a signal is triggered?
My personal experience is to not give data to your view components, don't bind them. For example, set your text value to an empty string or don't set it, set your image component source to an empty string or don't set it at first. When your signal comes in with data ready, you assign the data to the views at that time.

Implementation of glutdisplayFunc()

I've used glutdisplayFun(void(*func)) in several of my program to sets the callback display to the current window.And by the use of it, i've rendered different things on the screen. By looking at the documentation of glut, passing null to it is illegal and we can't deregister it also.
The problem is that as we can't deregister it and i write a set of code to display the mainmenu(i.e as shown in the game). And i like to change to next window on the keypress(i.e play the game by clicking on the option play present in the mainmenu).
How to make the glutdisplayfunc call to the mainmenu inactive and and to set the glutdisplayfunc() for calling the next window.
std::%something%<std::function<void(void)>> displayFns;
void myDisplayFunc() {
for (auto& displayFn : displayFns)
displayFn();
}
Now register myDisplayFunc to GLUT and change the displayFns collection.
As for something, map<int, function<...>> would be a good start. Unordered map if you can guarantee your code doesn't need to be called in order. It starts to resemble good old BASIC times with line numbers, but I said upfront it will be a simple answer.
That's not how I would do it, but should do the trick for a quick'n'easy solution.
Funny thing with this is that you can create sets of those to have one element appear in more than one choice rather easily. So maybe it's not that bad after all.

How to collect data and pass it around

I should find another interest because this one is taking the life out of me quickly. Seems like a lot of people are confused about the intricacies of MFC code, including me. I have an MFC Dialog Box application that creates several dialogs that you navigate to using the typical back or next function. Along the way you collect data via radio group buttons, list boxes and various other controls. For the most part I understand how to get a handle on the data by using the m_ variables provided by the AFX maps throughout the code for each distinct dialog. At the end - and sometimes during - the data collection/selection process gathered by dialogs, I need to do things with what has been collected. I may need to take the data from one dialog and modify the next based on the previous. It seems like when you move through the dialogs the data from the last is lost unless you save it somehow. I know that there are dozens of ways to do this and I have toyed with several of them, from object passing, to creating new classes, new structures, global variables, pointers, whatever.... My concern is, I need a data structure of some sort to stay up and active in memory long enough for my user code to do something with it. That is the problem I think, I don't know in MFC how to deal with this. I have currently decided to go with a struct called dlg_DataHandler (to house collected data from each dialog) with a few test members in a .h file. It has been typedef'd as a pointer. I am creating a variable of this type and setting it = new dlg_DataHandler, but the data isn't getting passed around like I want from dialog to dialog. One thing that I wonder about is, I don't know exactly where to place the "new" statement for creating the variable. Its as if data is not flowing to and from the structure as it should. Anyway here is some of the code:
// file1.h
typedef struct dlg_DataHandler {
int var;
char* String;
int RepetitionRadio; // radio button data
constructor here
} *dlgDataHandler;
extern dlgDataHandler DlgData;
//*****************
// file2.cpp
dlg_DataHandler DlgData = new dlg_DataHandler; // not located anywhere in peticular just in the code since I DON'T KNOW where to put it. DlgData->member gets loaded in the dialog .cpp files to try collect data, but it doesnt seem to be passing data across the different windows.
Put the variable in your main application class (the one derived from CWinApp) and call new in InitInstance(). You can then use AfxGetApp() to gain access to the application instance, and so your variable, from anywhere else in the code.

IFileOperation and the progress dialog

so, I am working on this shell namespace extension that handles a kind of ZIP file (let's call it ZOP) like a folder.
Everything is in place, and file operations are processed through IFileOperation and IStream.
The thing is, when copying a file into my virtual ZOP folder, calling IStream::Commit is not trivial, and can take significant time, so I'd like to provide additional feedback to the user (and allow her to cancel the operation).
I already have a progress callback mechanism that kicks in when the stream is committed. What I've done for now is a custom dialog, including a progress bar, that pops up whenever IStream::Commit is called.
However, I can't seem to find the hWnd of the standard progress dialog so that mine can be modal (which means that my dialog can be hidden by the progress dialog itself, which defeats the purpose of my dialog).
I could go the IFileOperation::SetProgressDialog way, creating a bridge to IOperationsProgressDialog, but I'd still have to do some dirty code to find the progress bar from a stream I've not created - all I can think of to pass data around is the TLS, and boy do I hate this solution, akin to using a global variable.
Thoughts about retrieving the window handle or subclassing the standard dialog ?
Note: I've observed that sometimes, for relatively short operations, the standard dialog appears after the stream is flushed. Which is uncool too, as my custom dialog appears and goes away even before the operations seems to start.
Update: I've found the progress window using EnumWindows/FindWindowEx as the window has the Dialog class with a DirectUIHWND child. The funny thing is, when instantiating my dialog using DialogBoxParam() (in a distinct thread from IStream::Commit()), the call hangs even before my dialog is displayed, as it is getting stuck in NtUserCallHwndParamLock.
Sounds like a job for spy++, get the class name of the window who's hwnd your looking for and call FindWinow or FindWindowEx.