Questions to experienced (plugin) developers

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Hacker, petermad, Stefan2, white

Post Reply
User avatar
Dalai
Power Member
Power Member
Posts: 9963
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Questions to experienced (plugin) developers

Post by *Dalai »

Hey there :),

I'm currently trying to write my first (real) file-system plugin, so please bear with me. There are some questions I'd like to ask the experienced (plugin) developers among you.
  1. How can I implement a properties dialog (called "property sheet" in the filesystem plugin SDK/help)? I tried a Delphi VCL form and it shows correctly but it makes a new button in the Windows taskbar and doesn't block TC. I analysed some other WFX plugins and saw a function named CreatePropertySheetPage in one of them. I've never dealt with it so I don't know how to use it. Yes, I read in the MSDN, but I guess there's more to it than just this function (the property sheet has to have some parent window, doesn't it?).
  2. How can I implement and especially test Unicode functionality? I don't have any experience there. To make it even more complicated: I'm using Delphi 5. There are types like PWideChar and WideString in there but I don't know if it's enough to cast the ANSI string types to the Unicode types ...
  3. The filesystem plugin SDK says about FsExtractCustomIcon:
    RemoteName
    This is the full path to the file or directory whose icon is to be retrieved. When extracting an icon, you can return an icon name here - this ensures that the icon is only cached once in the calling program.
    How do you return something with this function declaration?

    Code: Select all

    function FsExtractCustomIcon(RemoteName:pchar;ExtractFlags:integer; var TheIcon:hicon):integer; stdcall;
    It's just a local variable and the compiler says that the assigned value is never used if I do something like this:

    Code: Select all

    RemoteName:= PChar(Format('%s.%s', [PLUGINNAME, typ]));
I'm sure there will be more questions but that's all for now. Thanks for reading.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
Dalai
Power Member
Power Member
Posts: 9963
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Hey, that's too much information! ;)

I solved the problem with the properties dialog. One can use a VCL form but one has to make sure to set its Application.Handle to TC's MainWin (I wasn't aware of the Application object's importance in a DLL).

The remaining issues are still open, though. It would be great if someone could answer these questions.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

1. You should show your own properties dialog manually if your FsExecuteFile is called with verb properties. If you return FS_EXEC_YOURSELF, TC will show its simple dialog.

2. You can't simply cast ANSI strings to Unicode ones: ANSI strings contain 1-byte characters while Unicode ones contain 2-byte characters. If you really need to convert one to another, use MultiByteToWideChar/WideCharToMultiByte API functions with encoding CP_ACP. However if you write plugin for modern TC, you can simply leave ANSI functions empty (just stubs returning errors) and operate with only wide char strings and functions (if they aren't available in your prorgamming environment, maybe it is easier to write ANSI plugin?).

3. You can't assign a value to RemoteName of course. You should treat it as a buffer (array of char with size MAX_PATH, i.e. 260) where you can write path to locally available icon file (e.g. placed into temp dir) by simple copying characters from your local string variable to it (don't forget to add zero character #0 after path, so you can write up to 259 characters plus terminating #0 to RemoteName). You can simply use lstrcpyn/lstrcpynA/lstrcpynW API function to copy characters (they will also add terminating zero character):

Code: Select all

lstrcpyn(RemoteName, PChar(Format('%s.%s', [PLUGINNAME, typ])), MAX_PATH);
User avatar
Dalai
Power Member
Power Member
Posts: 9963
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Post by *Dalai »

Sorry for the late response, I was busy coding the last few days ;). Thanks for your answer.
MVV wrote:1. You should show your own properties dialog manually if your FsExecuteFile is called with verb properties. If you return FS_EXEC_YOURSELF, TC will show its simple dialog.
That's not what I meant. The question was how to create a custom dialog. But that's resolved now since a VCL form can be used.
2. You can't simply cast ANSI strings to Unicode ones: ANSI strings contain 1-byte characters while Unicode ones contain 2-byte characters. If you really need to convert one to another, use MultiByteToWideChar/WideCharToMultiByte API functions with encoding CP_ACP.
OK, I will look into it.
However if you write plugin for modern TC, you can simply leave ANSI functions empty (just stubs returning errors) and operate with only wide char strings and functions (if they aren't available in your prorgamming environment, maybe it is easier to write ANSI plugin?).
Mmh, that may be possible for most functions but not for all of them, I guess. I intend to create translation files for my plugin but I don't want to reinvent the wheel and just use TIniFile class (which is of course ANSI only in Delphi 5). However, I intend to port my plugin to 64 bit as well and use Lazarus for this. Maybe the situation is better there; I don't know yet.

However, your answer doesn't cover all of my second question. Let's assume I think I'm done with implementing Unicode functions. How can I test if they are working correctly?
3. You can't assign a value to RemoteName of course. You should treat it as a buffer (array of char with size MAX_PATH, i.e. 260) where you can write path to locally available icon file (e.g. placed into temp dir) by simple copying characters from your local string variable to it (don't forget to add zero character #0 after path, so you can write up to 259 characters plus terminating #0 to RemoteName). You can simply use lstrcpyn/lstrcpynA/lstrcpynW API function to copy characters (they will also add terminating zero character):

Code: Select all

lstrcpyn(RemoteName, PChar(Format('%s.%s', [PLUGINNAME, typ])), MAX_PATH);
OK, so this would work as well?

Code: Select all

StrCopy(RemoteName, PChar(Format('%s.%s', [PLUGINNAME, typ])));
//or
StrLCopy(RemoteName, PChar(Format('%s.%s', [PLUGINNAME, typ])), MAX_PATH);
Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Post Reply