PDA

View Full Version : "file launching" LWM, without multiple app instances??



jeric_synergy
12-09-2018, 02:32 PM
It's sometimes convenient to just double click on an LWO file and have LWM load it.

But, if I do the same w/another file, a duplicate instance of LWM is launched.

How does one prevent that, and simply have the currently running LWM instance load the mesh as a second (or third, etc) object?

Andy Webb
12-10-2018, 10:18 AM
I have the same issue, and it would be more than useful to have an answer one way or the other

MonroePoteet
12-10-2018, 03:27 PM
The application itself must be coded to do this, and clearly Modeler is not. When you double-click on a file in Windows, it invokes the "default action" for that file (the bolded one at the top of the right-click menu), which in the case of an LWO file is "Open" which will start the associated application (Modeler). This is purely a Windows function, whether it's Lightwave or not.

To implement this on Windows (from my developer days) the application (Modeler) must detect during its very early startup (like first thing) whether there's an already running instance of itself and if so, "forward" the ShellExecute=>Open() request to the already existing instance by setting up a DROPFILES structure in global shared memory with GlobalAlloc() and sending a WM_DROPFILES message to the other process via PostMessage(). The application must support dropping files onto it (which Modeler does).

When I implemented this, I used an EnumWindows() loop to scan all the processes on the system for an already existing instance of the target application (in my case the open-source image viewer FineView), but LW Modeler could hopefully ask the Hub whether Modeler was already running and get a pointer to Modeler's CWnd (or use CWnd::FromHandle(hwnd) with its HWND structure).

So, unless Modeler is coded to do the above, it won't work. Of course, you can drag-n-drop the LWO file to Modeler to achieve the same thing, but I don't think there's any way to have Windows convert a double-click on a file (invoking the default action of Open) into a Drop File onto an existing application.

I have no clue of how to do the same thing on Mac/OS.

Here's the source routine from my application (without the supporting FindFineView() routine using EnumWindows()):


BOOL CRandVideoDlg::DropFile(CString sFileName)
{
/*
* typedef struct _DROPFILES {
* DWORD pFiles; // offset of file list
* POINT pt; // drop point (coordinates depend on fNC)
* BOOL fNC; // see below
* BOOL fWide; // TRUE if file contains wide characters,
* // FALSE otherwise
* } DROPFILES, FAR * LPDROPFILES;
*/

CString sFileList;
DWORD nLength;
DWORD nTotalLength;

HGLOBAL hDropFiles;
DROPFILES *pDropFiles;
char *pFileList;

/*
* Find the FineView Process
*/

FindFineView();
if (m_pFineViewProc == NULL)
{
return(FALSE);
}

/*
* Get the length of the filename to drop
*/

nLength = sFileName.GetLength();

/*
* allocated global shared memory for the DROPFILES struct,
* the filename, and the two terminating nulls
*/

nTotalLength = sizeof(DROPFILES) + nLength + 2;
hDropFiles = GlobalAlloc(GMEM_FIXED,nTotalLength);
if (hDropFiles == NULL)
{
MessageBox("Failed to allocate Global Memory");
return(FALSE); // stop processing
}

/*
* typecast the global memory to a pointer we can use,
* and copy our list
*/

pDropFiles = (DROPFILES *)GlobalLock(hDropFiles); // get memory pointer
ZeroMemory(pDropFiles,nTotalLength); // put in the nulls

pFileList = (char *)pDropFiles;
pFileList += sizeof(DROPFILES);

strncpy((char *)pFileList,sFileName.GetBuffer(0),nLength);

pDropFiles->pFiles = sizeof(DROPFILES); // offset to list
pDropFiles->pt = CPoint(10,10); // drop at 10,10
pDropFiles->fNC = FALSE; // in client area
pDropFiles->fWide = FALSE; // not WIDE characters

/*
* Unlock it for use by another process
*/

GlobalUnlock(pDropFiles);

/*
* Must use PostMessage for some reason
*/

if (!m_pFineViewProc->PostMessage(WM_DROPFILES,(unsigned int)hDropFiles,0))
{
// call failed, free it ourself
MessageBox("Failed to post WM_DROPFILES");
GlobalFree(hDropFiles);
return(FALSE);
}

m_pFineViewProc->BringWindowToTop();
return(TRUE);
}


mTp

Andy Webb
12-10-2018, 04:17 PM
Well that's a pretty extensive answer :thumbsup:

MonroePoteet
12-10-2018, 10:43 PM
Well, thanks! :)

It sounds like it may be helpful, so I wrote a little Windows application to do the job if you're interested. It's called LWO_DoubleClick.EXE and you'll change the Default Program for LWO files to invoke it rather than Modeler.

The "installation steps" I'd recommend are:

1) Extract the EXE file from the ZIP file
2) Move the EXE to a common location, like C:\ or C:\Program Files\NewTek if you have privileges to do so, or wherever
3) Double click on the LWO_DoubleClick.EXE and it will ask for the location of the Modeler.EXE you want to use and hit OK
4) Right-click on one of your LWO files, and select Open with=>Choose default program...

143543

5) Press "Browse..." and navigate to the LWO_DoubleClick.EXE file
6) Be sure the checkbox saying "Always Open Files of this type with this application" is checked

143544

7) Press OK

Note that after changing the default program for LWO files, their icons will change to that of LWO_DoubleClick:

143545

When you press OK, LWO_DoubleClick will be invoked, which will start up Modeler and send the specified LWO to it.

Any time Modeler isn't already running when you double-click on a LWO file, LWO_DoubleClick will bring up Modeler and do the Drop File. It may take a few seconds for Modeler to come up and the drop to complete.

Subsequent double-clicks on LWO files should send them immediately to Modeler. You may see a flash of the LWO_DoubleClick application's interface, but it should vanish automatically when the Drop File is complete. Of course, if the LWO file is large or has a lot of textures, Modeler may take a while to load it, as usual.

If you need to change the location of Modeler (e.g. a new installation), double click on the LWO_DoubleClick.EXE directly (not on an LWO file), which will bring up the dialog box allowing you to specify the new Modeler location.

Hope it helps!
mTp

P.S. with a little testing, there are cases where the FIRST double-click on an LWO file doesn't bring up Modeler correctly. This is probably because the location of Modeler hasn't been set up correctly. Double-click on the LWO_DoubleClick.EXE directly and specify the correctly location for Modeler

P.P.S. If there is a *different* version of Modeler already running, LWO_DoubleClick will use that one. The location stored by LWO_DoubleClick is only used if Modeler isn't already running.

Andy Webb
12-11-2018, 03:24 AM
Wow, someone has been busy.

Excellent work, I will give it a go! :D :thumbsup:

Cheers

MonroePoteet
12-11-2018, 08:37 AM
Hope it works for you! Since I already had the code to do the EnumWindows() scan, I just changed it to look for a window with "Modeler", "LightWave" and "NewTek" in the window title. I also had the code to do the PostMessage(WM_DROPFILES...), so I just had to extract it from the existing application and adapt it to the new one. A few tweaks here and there (e.g. storing the path to Modeler in the Registry) and one truly frustrating crash (storing and using a temporary CWnd pointer rather than its HWND handle!), and "Wahlah!": a new tool is born!

As I said, hope it works for you!

mTp

P.S. In case anyone in LWDG gets around to implementing this, I've attached the source code in a ZIP file. The key work is done in LWO_DoubleClickDlg.cpp. As I've said, I have no clue how to do the same thing in Mac/OS.