Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Adding a dll function to QM
#1
Hello Gintaras,

this one is for you, as I guess you're the only one who can answer.

I'd like to use a function from Shlwapi.dll

BOOL PathMakeSystemFolder(
_In_ LPTSTR pszPath
);

WinFunctions in QM contains some, but seems read-only.

I tried this in a macro but always get 0 as result, so i think this code is wrong.

Code:
Copy      Help
dll Shlwapi.dll #PathMakeSystemFolder @*pszPath
_i=PathMakeSystemFolder(@dest)

1.What is the correct way how to use it?
2. is the way you give available for any dll?

Thanks.
#2
To add Windows API functions to QM:
1. Type function name in macro. If it's colored, you can use it; goto 8.
2. Look in status bar. If it contains function declaration, you can use it; goto 8.
3. Type WINAPIV.FunctionName. If it becomes colored, you can use it; goto 8.
4. Type WINAPI7.FunctionName. If it becomes colored, you can use it; goto 8.
5. Download and install More Windows API declarations for QM
6. Type WINAPI2.FunctionName. If it becomes colored, you can use it; goto 8.
7. Convert declaration from C++ to QM.
8. If need Unicode version, and function name does not end with W, append W and goto g1.

Most Windows API functions with string parameters have 2 versions, eg PathMakeSystemFolderA (ANSI, strings are lpstr ($)) and PathMakeSystemFolderW (Unicode UTF-16, strings are word* (@*)). PathMakeSystemFolder actually does not exist, and QM then picks the A version. Declaration examples:
dll Shlwapi #PathMakeSystemFolder $pszPath ;;ANSI version
dll Shlwapi #PathMakeSystemFolderW @*pszPath ;;Unicode version

It's better to use W version. ANSI version will not work with strings containing non-ASCII characters, because default QM string encoding is UTF-8. Example:
str sf.expandpath("$my qm$\sys")
mkdir sf
if(!PathMakeSystemFolderW(@sf)) out _s.dllerror ;;operator @ converts from QM string encoding to UTF-16
#3
Thanks for detailed answer.

Now i'm quite perplex, as I wanted to adapt QM ChangeFolderIcon, as
MSDN documentation seems to say that SHGetSetFolderCustomSettings is somehow obsolete and deprecated.
see http://msdn.microsoft.com/en-us/library/...85%29.aspx
I stumbled upon a document giving the way to do the same thing in "modern" way.
see http://msdn.microsoft.com/en-us/library/...85%29.aspx

Actually my function is now working (returns 1 and no more 0) but
directory does not become system as supposed to.

I'm afraid all that is to much under the hood for my skills...
#4
I don't know exactly, sorry, i just repeat what I read in MSDN documents..

Anyway, my code *seems* fine, except tht it messes with the icon cache, as new folder icons aren't refreshed.
And if i do it twice, explorer shows an icon that is not the right one (if i open it with an icon editor,
its preview is a wrong one, but the icon program shows the one is supposed to be new)

I tried SHChangeNotify, but no chance.

Any idea?


Attached Files Image(s)
   
#5
Macro change folder icon - create desktop.ini
Code:
Copy      Help
str icon.expandpath("$qm$\image.ico")
str sf.expandpath("$my qm$\sys")
mkdir sf
;if(!PathMakeSystemFolderW(@sf)) out _s.dllerror
SetAttr sf FILE_ATTRIBUTE_READONLY 1
str ini.from(sf "\desktop.ini")
iff ini
,SetAttr ini 0
,del- ini
str s=
F
;[.ShellClassInfo]
;IconFile={icon}
;IconIndex=0
s.unicode
s.setfile(ini)
SetAttr ini FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM
;IconResource={icon}
#6
yes my code is quite the same.

But there is still a problem with thumbnails, though moving the directory to another place does show the
good icon.
If you have a clue.

I tried some google found solution but none worked.
#7
Delete ini file.
Code updated.
#8
Does not work either.
here's my complete code, called from a function triggered by shellmenu trigger (gives the name of the folder).

Macro Macro24
Trigger $sm "test" 0x1 "" ""     Help - how to add the trigger to the macro
Code:
Copy      Help
;\
function $files
ARRAY(str) a=files
str dest=a[0]

str file
file=F"{dest}\Folder.ico"
iff(file) del file
file=F"{dest}\desktop.ini"
iff(file) del file
;
str Chemin="T:\icônes"  
OpenSaveDialog(0 _s "Icônes[]*.ico" "*.ico"  Chemin "rr")
;;;
;
str desk=
;[.ShellClassInfo]
;ConfirmFileOp=0
;NoSharing=1
;IconFile=Folder.ico
;IconIndex=0
;InfoTip=

cop- _s F"{dest}\Folder.ico"
SetAttr(F"{dest}\Folder.ico" FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM 0|1)

desk.unicode
desk.setfile(F"{dest}\desktop.ini")
SetAttr(F"{dest}\desktop.ini" FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM 0|1)

_i=GetAttr(dest)
if(_i&FILE_ATTRIBUTE_SYSTEM)
,SetAttr(dest FILE_ATTRIBUTE_SYSTEM 2)
else SetAttr(dest FILE_ATTRIBUTE_SYSTEM 0|1)
_s.all

As said works except that explorer does not refresh the icon folder except if I move it in another place.
If you see where the problem stands..
#9
and this one line code still works beautifully, but i'd like to understand...

Code:
Copy      Help
;\
function $files
ARRAY(str) a=files
str dest=a[0]

str Chemin="T:\icônes"  
OpenSaveDialog(0 _s "Icônes[]*.ico" "*.ico"  Chemin "rr")

ChangeFolderIcon(dest _s)


:twisted: Confusedhock: Confusedhock: <sigh>....


Forum Jump:


Users browsing this thread: 1 Guest(s)