|
Post by sarossell on Dec 20, 2019 13:30:51 GMT -5
Does anyone remember a program called Perfect Menu? It allowed you to attach shortcut taskbars to the right-click context menu in Windows. The company that developed it, for some reason, no longer sells or supports it. The last version was available 18 years ago. It runs in Windows 10, but it has a problem that prevents it from saving the settings. I'd like to find a way to re-create this program using Liberty BASIC, if it's possible.
My experience is limited, and I'm not looking for anyone to do it for me, but I thought it might be an interesting challenge for some folks here, and I'd really enjoy learning how. I suspect it may be as easy as a DLL call, but in my limited experience, I couldn't figure it out.
Anyone interested? ...Pretty please! Any hints or tips would be greatly appreciated.
P.S.: I also have an idea for reviving a really useful program called TreePad which died a similar fate recently.
|
|
|
Post by Chris Iverson on Dec 20, 2019 14:13:15 GMT -5
Do you have a link to the program? If it was available 18 years ago, and never updated since then, then I suspect I know what the issue is. (Although there are probably additional issues nowadays, anyway, like display scaling.)
As for doing it in LB, I have a couple of ideas on how it could be done, but it probably wouldn't be as responsive as that program likely is, since it would involve lots of manually searching the "currently open window" list. (All GUI display objects on Windows, including menus, are implemented as "windows". A menu opening up would appear as a new window being created.) You'd also have to keep searching the list to see if the menu you're currently "attached" to has been closed, so you can close your windows.
The "proper" way is to use a window creation hook, which notifies your program every time a window is created, but that requires a separate DLL to use properly. This is also an additional problem in that 32-bit DLLs can't be injected into 64-bit processes, and vice-versa, so you have the possibility of missing notifications. You could also do a CallWndProc hook, and filter it down to window creation messages for the popupmenu class, which would eliminate the 32/64-bit issue, but you'd still need a separate DLL for that. LB simply wouldn't have the ability to keep of with the flood of notifications that would generate.
I think an accessibility hook would also work, but that would also basically require a separate DLL since it needs to use COM to access the IAccessible interface. (It's possible to use COM directly from LB, but very wonky.)
|
|
|
Post by sarossell on Dec 20, 2019 15:20:33 GMT -5
Do you have a link to the program? The program is no longer on the developer's web site and they refuse to provide any support. But I have the trial setup version here (attached).
|
|
|
Post by sarossell on Dec 21, 2019 17:58:15 GMT -5
Sorry if this is getting a bit off-topic. I'm genuinely interested in how Liberty BASIC handles DLLs, particularly in this specific situation.
In a vain attempt to try to lean something about DLLs, I found a program called DLL Export Viewer that lets you either load a DLL to list its internal functions or select a running program to list the DLLs it's using.
I was able to dig out the functions from the only included DLL in the Perfect Menu package (_mpdll.dll). They are as follows:
EMDllMouseProc dllGetHookToDLL g_dll_FilterMsg g_dll_hook
I have no idea what these mean or how they might work, but I do see some key words like "Mouse" and "hook". (I'm really showing my ignorance here.)
If I do a similar search of all DLLs accessed by the running program, I get a long list of DLLs that includes a number of usual suspects. But there are two entries listed for the running program. One is pmenu32.TMP0 and the other is the expected pmenu32.exe. The .TMPO appears to access fewer DLLs than the .EXE. Below are listed the DLLs for the .TMPO. After that, are listed the additional DLLs listed for the .EXE.
pmenu32.TMP0
advapi32 bcrypt bcryptPrimitives combase comctl32 comdlg32 dwmapi gdi32 imm32 kernel.appcore kernel32 kernelbase msctf msvcrt ntdll ole32 powrprof rpcrt4 sechost shcore shell32 shlwapi user32 uxtheme windows.storage winspool.drv
pmenu32.exe
sfc sfc_os setupapi oleaut32 cfgmgr32 aclayers apphelp
|
|
|
Post by Chris Iverson on Dec 21, 2019 18:58:34 GMT -5
Yeah, I can't get PerfectMenu to run at all, and it doesn't help that I suspect that the DRM/registration code is a DOS program that doesn't run on 64-bit windows.
|
|
|
Post by sarossell on Dec 21, 2019 19:07:32 GMT -5
Yeah, I can't get PerfectMenu to run at all, and it doesn't help that I suspect that the DRM/registration code is a DOS program that doesn't run on 64-bit windows. Yeah, I'm not surprised. I appreciate you trying though!
The main program runs fine in 32-bit Windows 32, but 64-bit wasn't even a concept 18 years ago beyond maybe Atari's Jaguar game system.
The registration program is worthless anyway. It's just a form to email thing. It doesn't actually do anything useful.
Any suggestions where I might go from here? (be nice!) ;@)
|
|
|
Post by Chris Iverson on Dec 21, 2019 20:43:39 GMT -5
Well, I was trying to confirm my guess, but if I can't get it to run, I won't be able to confirm it.
Still, at least I can make the guess public.
There's two ways a program can save settings. Files, or the registry.
Considering this was developed as a Windows 95/98 program, I doubt it uses the registry. It's more likely that it'll use something like an .ini file.
Most programs of that era either stored their settings as an INI file in the Windows folder, or stored it as an ini file in the program's folder. This worked fine on 95/98, because there was no security on the system at all. Anyone could do anything.
What I'm guessing is that it can't save the file properly because modern security configurations prevent general users from making system-wide changes. To confirm that guess, I was going to run the program as Administrator to see if it's able to access the file it needs, and then I was going to find the file itself, and modify the permissions on it to allow everyone to edit it.
Basically, my two suggestions are exactly that:
Run the program as Administrator. This can be considered a fix if you're willing to do that each time.
or
Find the config file, and grant "Write" or "Full Control" permissions on it to Everyone.
|
|
|
Post by sarossell on Dec 21, 2019 21:06:59 GMT -5
I appreciate your effort, though my concern is not about it's ability to save the settings. It's a moot issue, since I can't register it out of the 30 day trial.
You are correct about the .ini file. It does exactly that. But it also hides the registration info in the registry.
My motivating concern is how to replicate this function in Liberty BASIC. It's so far above my head I don't even know how to start. My guess is finding the right DLL functions. But that's the extent of my understanding so far.
|
|
|
Post by Chris Iverson on Dec 22, 2019 0:27:50 GMT -5
Well, the most basic version of this I can think of involves using a timer to constantly call the FindWindowA() API looking for any window with the class "#32768". If you find an existing window of that class, that means a menu is open. You can use the handle returned by FindWindowA() in an API call like GetWindowRect() to find out where on the screen it is. Using that information, you can open up an LB window relative to where on the screen the menu is. Even while the window is open, though, you'll want to keep the timer going, because once that menu stops being found, that means the menu has been closed, and you'll want to close your window as well.
|
|
|
Post by sarossell on Dec 22, 2019 1:09:31 GMT -5
Very encouraging. Thank you!
|
|
|
Post by Rod on Dec 22, 2019 7:42:43 GMT -5
|
|
|
Post by sarossell on Dec 22, 2019 12:05:34 GMT -5
Rod: That is the company, yes. But they no longer sell or support the program I'm interested in.
|
|
|
Post by xxgeek on Oct 28, 2021 17:02:01 GMT -5
I realize this is an old thread, but in case you want to try an old trick....
A lot of dated trial software around that era could be used forever by just renaming the exe file that runs it. An old trick I remembered while reading this.
|
|