[Development] External WLX plugins loader
Moderators: Hacker, petermad, Stefan2, white
[Development] External WLX plugins loader
I need some help: How to load/unload WLX plugin in Delphi application?
Can anybody give me Delphi example, that will: on button press load a WLX plugin (e.g. IEView or Imagine) and show it on form; on second button press unload plugin and clear form.
I tried to code something, but without good result (unloading causes Exception). So working example is needed...
Can anybody give me Delphi example, that will: on button press load a WLX plugin (e.g. IEView or Imagine) and show it on form; on second button press unload plugin and clear form.
I tried to code something, but without good result (unloading causes Exception). So working example is needed...
Last edited by Alextp on 2006-06-28, 09:05 UTC, edited 1 time in total.
Loading and unloading could be done with pure winapi, no delphi specific is envolved.
I just try a little example and it works ok with most of the WLX plugins.
There was some software exceptions with SynPlus, but FileInfo, Imagine works fine.
Here is C example
Load
Unload
Hope this snippet will be helpfull.
I can share an example project, it is written with Borland C++ Builder 2006.
I just try a little example and it works ok with most of the WLX plugins.
There was some software exceptions with SynPlus, but FileInfo, Imagine works fine.
Here is C example
Load
Code: Select all
HMODULE hLib = LoadLibrary("fileinfo.wlx");
if (!FLib)
return;
typedef void __stdcall (*TListSetDefaultParams)(ListDefaultParamStruct* dps);
// according to docs ListSetDefaultParams is called before ListLoad
TListSetDefaultParams ListSetDefaultParams = (TListSetDefaultParams)GetProcAddress(hLib , "ListSetDefaultParams");
if (ListSetDefaultParams)
{
ListDefaultParamStruct s;
ZeroMemory(&s, sizeof(ListDefaultParamStruct));
s.PluginInterfaceVersionLow = 1; // I don't know exact number, so it is my guess
s.PluginInterfaceVersionHi = 1;
strcpy(s.DefaultIniName, "lsplugin.ini");
s.size = sizeof(s);
ListSetDefaultParams(&s);
}
typedef HWND __stdcall (*TListLoad)(HWND ParentWin,char* FileToLoad,int ShowFlags);
TListLoad ListLoad = (TListLoad)GetProcAddress(hLib, "ListLoad");
if (!ListLoad)
return;
HWND hWlx = ListLoad(hParent, "some_file", 0); // hParent is HWND of the parent (Lister) window
Code: Select all
typedef void __stdcall (*TListCloseWindow)(HWND ListWin);
TListCloseWindow ListCloseWindow =
(TListCloseWindow)GetProcAddress(hLib, "ListCloseWindow");
if (ListCloseWindow)
ListCloseWindow(hWlx); // hWlx is a HWND, returned by plugin
else
{
// if plugin did not export ListCloseWindow, then, according to docs, TC will use DestroyWindow
DestroyWindow(hWlx);
}
I can share an example project, it is written with Borland C++ Builder 2006.
2poiuytr
Please share a project (compiled!) that can load/unload Imagine for some picture.
I have problems with Imagine.
Plugins that work:
IEView, OOView, TTFViewer
Problems:
- Imagine: doesn't show (form remains empty)
- ICLView: doen't occupy whole window, only small part of it
- LinkInfo: External Exception in my app, but plugin shows
My code, it's almost as yours:
Please share a project (compiled!) that can load/unload Imagine for some picture.
I have problems with Imagine.
Plugins that work:
IEView, OOView, TTFViewer
Problems:
- Imagine: doesn't show (form remains empty)
- ICLView: doen't occupy whole window, only small part of it
- LinkInfo: External Exception in my app, but plugin shows
My code, it's almost as yours:
Code: Select all
var
WlxHLib: THandle = 0;
WlxHWnd: THandle = 0;
procedure WlxFree;
var
Proc2: TListCloseWindow;
begin
if WlxHLib=0 then Exit;
if WlxHWnd<>0 then
begin
@Proc2:= GetProcAddress(WlxHLib, 'ListCloseWindow');
if @Proc2<>nil then Proc2(WlxHWnd) else DestroyWindow(WlxHWnd);
end;
Sleep(100);
FreeLibrary(WlxHLib);
WlxHLib:= 0;
WlxHWnd:= 0;
end;
procedure WlxLoad(const fPlugin, fFile: string; ParentWnd: THandle; const DefIni: string);
var
hLib: THandle absolute WlxHLib;
hWnd: THandle absolute WlxHWnd;
Proc0: TListGetDetectString;
Proc1: TListLoad;
Proc3: TListSetDefaultParams;
dps: TListDefaultParamStruct;
buf1: array[0..8*1024] of char;
begin
WlxFree;
hLib:= LoadLibrary(PChar(fPlugin));
if hLib=0 then Exit;
@Proc0:= GetProcAddress(hLib, 'ListGetDetectString');
if @Proc0<>nil then
begin
FillChar(buf1, SizeOf(buf1), 0);
Proc0(buf1, SizeOf(buf1));
end;
@Proc3:= GetProcAddress(hLib, 'ListSetDefaultParams');
if @Proc3<>nil then
begin
FillChar(dps, SizeOf(dps), 0);
dps.Size:= SizeOf(dps);
dps.PluginInterfaceVersionLow:= 30;
dps.PluginInterfaceVersionHi:= 1;
lstrcpy(dps.DefaultIniName, PChar(DefIni));
Proc3(@dps);
end;
@Proc1:= GetProcAddress(hLib, 'ListLoad');
if @Proc1=nil then begin FreeLibrary(hLib); hLib:= 0; Exit end;
try
hWnd:= Proc1(ParentWnd, PChar(fFile), lcp_ansi or lcp_forceshow);
if hWnd=0 then
ShowMessage('Failed to load')
else
ShowMessage('Loaded');
finally
end;
end;
Check this out. Sources with compiled exe inside.Alextp wrote:2poiuytr
Please share a project (compiled!) that can load/unload Imagine for some picture.
IMHO Lister sets size of the plugin's window by itself, didn't you forget to do this in your project (set initial size and update it on resize event)? I think this will solve your problem with Imagine.Problems:
- Imagine: doesn't show (form remains empty)
- ICLView: doen't occupy whole window, only small part of it
I have the same experience with my project and with Lister itself.- LinkInfo: External Exception in my app, but plugin shows
Yep, main line is the same.My code, it's almost as yours
Code: Select all
SetWindowPos(WlxHwnd, // HWND, returned by plugin
HWND_TOP,
0,
0,
Panel1->ClientWidth,
Panel1->ClientHeight,
NULL);
Nice to hear!Alextp wrote:Thanks, now all works!
May be Imagine detects that it is launched in the quick view mode (Imagine will hide button bar in that mode). One technique to determinate QuickVeiwMode is to perform a FindWindow("TLister", 0) and check returned handle. Try to play with your parent class name (make it 'TLister').Imagine doesn't show its toolbar, even when I check this in options.
Your project have to be as much close to Lister as possible to use most of the wlx plugins without problems.
It will be hard to adopt plugin for your project when plugin author used some hacks (e.g. messing with Lister's main menu).
Poor wlx api is the cause of this (CG, please, do something!).
Class name of TForm descendant or of TPanel on which plugin is shown? And how to change class name in both cases?One technique to determinate QuickVeiwMode is to perform a FindWindow("TLister", 0) and check returned handle. Try to play with your parent class name (make it 'TLister').
Tried to change form type name to TLister, no effect.
I tried both, but only changing class name of the main form works.Alextp wrote:Class name of TForm descendant or of TPanel on which plugin is shown?
Ok, here is what I did:
* changed name of the main form to 'Lister' (class name of the main form became 'TLister');
* called ListLoad with HWND of the main form;
* resized plugin window over main form;
* yey, Imagine toolbar is visible

Check the sources.
To change Panel class name just create the descendant of the TPanel with class name TLister.And how to change class name in both cases?
To change Form class name just name your main form as 'Lister' and you will see that its class name will automatically change to 'TLister' (at least in Builder I can do this, hopefully it is the same thing with Delphi or you can use the same trick as with Panel).
Confirmed...tried both, but only changing class name of the main form works.
Ok, here is what I did:
But any way to display it on TPanel? I tried this:
Code: Select all
type
TLister = class(TPanel)
end;
Maybe, Imagine looks only for normal windows, not for child windows/controls?
Of course! You can easily place plugin window over Panel without making this Panel parent of the this window by using SetWindowPos(.. HWND_TOP ..).Alextp wrote:But any way to display it on TPanel?
True if Imagine use FindWindow function (according to msdn FindWindow retrieves the handle to the top-level windows only).Maybe, Imagine looks only for normal windows, not for child windows/controls?
Good work!What I'm doing:
http://atorg.net.ru/files/util_WdxWlxGuide.zip
Plugin's window doesn't have any caption, it can not be resized by mouse or smth.. At least those plugins I tried (FileInfo, Imagine, IEView, ICLView..).Alextp wrote:This will be odd... Window caption will over panel, window may be resized indep. of panel and etc...Of course! You can easily place plugin window over Panel without making this Panel parent of the this window by using SetWindowPos(.. HWND_TOP ..).
Not nice.