Mark Williams 14 Posted January 7, 2020 Does anyone know a way of getting the above to function in 64 bit or is there an alternative? Share this post Link to post
Dave Nottage 557 Posted January 8, 2020 3 hours ago, Mark Williams said: Does anyone know a way of getting the above to function in 64 bit or is there an alternative? This person seems to have it working in 64-bit: https://forums.embarcadero.com/message.jspa?messageID=671467&tstart=0 Share this post Link to post
FredS 138 Posted January 8, 2020 23 minutes ago, Dave Nottage said: working in 64-bit Works fine in Berlin+ Win64.. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 12 hours ago, Dave Nottage said: This person seems to have it working in 64-bit: https://forums.embarcadero.com/message.jspa?messageID=671467&tstart=0 His opening words are Quote I'm running a 32-bit app I can't see any reference in the rest of the post to 64 bit. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 (edited) 13 hours ago, FredS said: Works fine in Berlin+ Win64.. I had it working in 32 bit using very similar code to that in the forum message which Dave Nottage has linked above. I can't get it to work in 64 bit. The references to "Shell32" throw up unrecognised errors and I am not sure what to replace them with. Have had a look at the Windows documentation and it says its a Shell32 function. Can you explain what you did to get it to work in 64bit please? Edited January 8, 2020 by Mark Williams typos Share this post Link to post
Remy Lebeau 1394 Posted January 8, 2020 (edited) 6 hours ago, Mark Williams said: I can't get it to work in 64 bit. The references to "Shell32" throw up unrecognised errors and I am not sure what to replace them with. Why not simply declare the function yourself in your own code? function SHOpenFolderAndSelectItems(pidlFolder: PCIDLIST_ABSOLUTE; cidl: UINT; apidl: PCUITEMID_CHILD_ARRAY; dwFlags: DWORD): HRESULT; stdcall; external 'shell32.dll'; Edited January 8, 2020 by Remy Lebeau Share this post Link to post
Mark Williams 14 Posted January 8, 2020 40 minutes ago, Remy Lebeau said: Why not simply declare the function yourself in your own code? function SHOpenFolderAndSelectItems(pidlFolder: PCIDLIST_ABSOLUTE; cidl: UINT; apidl: PCUITEMID_CHILD_ARRAY; dwFlags: DWORD): HRESULT; stdcall; external 'shell32'; I've tried that. I can't find which unit declares PCUITEMID_CHILD_ARRAY and my debugger is also unhappy with the reference to 'shell32'. Can Shell32 be referenced in 64 bit apps? Share this post Link to post
David Heffernan 2345 Posted January 8, 2020 If you have 32 bit code that works then that same code will work in 64 bit. We can't see your code. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 2 minutes ago, David Heffernan said: If you have 32 bit code that works then that same code will work in 64 bit. We can't see your code. It's pretty much the same as mentioned in the link above. However: //Following is to enable opening of a folder and selecting of file const OFASI_EDIT = $0001; OFASI_OPENDESKTOP = $0002; {$IFDEF UNICODE} function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32 name 'ILCreateFromPathW'; {$ELSE} function ILCreateFromPath(pszPath: PChar): PItemIDList stdcall; external shell32 name 'ILCreateFromPathA'; {$ENDIF} procedure ILFree(pidl: PItemIDList) stdcall; external shell32; function SHOpenFolderAndSelectItems(pidlFolder: PItemIDList; cidl: Cardinal; apidl: pointer; dwFlags: DWORD): HRESULT; stdcall; external shell32; function OpenFolderAndSelectFile(const FileName: string): boolean; var IIDL: PItemIDList; begin result := false; CoInitialize(Nil); IIDL := ILCreateFromPath(PChar(FileName)); if IIDL <> nil then try result := SHOpenFolderAndSelectItems(IIDL, 0, nil, 0) = S_OK; finally ILFree(IIDL); CoUninitialize; end; end; This works fine in older version of Delphi and 32bit apps. It doesn't compile on 64 bit platform. I noted that Remy enclosed his references to Shell32 in single quotes. I have done the same and it now compiles. However, it doesn't work. Doesn't throw up any errors it just doesn't do anything. It fails to create a PItemIDList on the call to ILCreateFromPath. I have read on the Microsoft forums (MS Forum) that this may be a bug with Windows 10 64 bit only. @FredS mentions above that he has it working in Berlin and 64 bit. He doesn't mention if that is on Windows 10 or not. Share this post Link to post
FredS 138 Posted January 8, 2020 3 hours ago, Mark Williams said: The references to "Shell32" throw up unrecognised errors shell32 is declared in Winapi.ShlObj in the implementation section. const shell32 = 'shell32.dll'; You in Berlin or UP, or something else? You know asking Qs without supplying sufficient information simply leads to what you see here.. Share this post Link to post
FredS 138 Posted January 8, 2020 (edited) 8 minutes ago, Mark Williams said: He doesn't mention if that is on Windows 10 or not On Windows 10 1903.18362.476. Also your code doesn't `CoUninitialize` if IIDL is nil. ..and what does GetLastError say when you get IIDL=nil? Edited January 8, 2020 by FredS 1 Share this post Link to post
Mark Williams 14 Posted January 8, 2020 31 minutes ago, FredS said: On Windows 10 1903.18362.476. Also your code doesn't `CoUninitialize` if IIDL is nil. ..and what does GetLastError say when you get IIDL=nil? 38 minutes ago, FredS said: shell32 is declared in Winapi.ShlObj in the implementation section. const shell32 = 'shell32.dll'; You in Berlin or UP, or something else? You know asking Qs without supplying sufficient information simply leads to what you see here.. Sorry. I mistakenly thought Shell32 was restricted to 32 bit and that I was looking another function. I will know better in future (hopefully). Delphi 10.3 update 1. Latest However see response to your last message. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 34 minutes ago, FredS said: On Windows 10 1903.18362.476. Also your code doesn't `CoUninitialize` if IIDL is nil. ..and what does GetLastError say when you get IIDL=nil? I found the code online some years ago. Hadn't noticed the failure to CoUninitialize. Thanks. I managed to get my old code to compile this evening by enclosing Shell32 in single quotes. I didn't realise that an error message would be generated if ILCreateFromPath returned nil. Thanks also for that suggestion. I can now see why my code was doing nothing. Unfortunately, the reason was rather embarrassing. for test purposes, I had hard coded the file path rather than use a dialog and as a result I was submitting a non-existent file! However, without your suggestion re GetLastError I would never have realised that (at least not for another few years). Share this post Link to post
David Heffernan 2345 Posted January 8, 2020 GetLastError is bad advice. COM doesn't report errors that way. If you would just show a complete, minimal example, it would be easy to help. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 22 minutes ago, David Heffernan said: GetLastError is bad advice. COM doesn't report errors that way. If you would just show a complete, minimal example, it would be easy to help. Possibly, however it worked a treat in this case and helped me an identify the problem. Please see my last post. As for the code I have posted it earlier (see a few posts back) and note Fred's comments as to UnCoinitialize. Share this post Link to post
Remy Lebeau 1394 Posted January 8, 2020 4 hours ago, Mark Williams said: I've tried that. I can't find which unit declares PCUITEMID_CHILD_ARRAY Then you need to grep the RTL source files to find it, or just add the declaration to your own code. 4 hours ago, Mark Williams said: my debugger is also unhappy with the reference to 'shell32'. The *debugger* doesn't care about DLL reference, so I assume you mean the *compiler* instead? 4 hours ago, Mark Williams said: Can Shell32 be referenced in 64 bit apps? Of course it can. Every Win32 API DLL can be, Microsoft ships both 32bit and 64bit versions of them. Share this post Link to post
Mark Williams 14 Posted January 8, 2020 3 minutes ago, Remy Lebeau said: Then you need to grep the RTL source files to find it, or just add the declaration to your own code. I did try that, but still couldn't find it any reference to it. 4 minutes ago, Remy Lebeau said: The *debugger* doesn't care about DLL reference, so I assume you mean the *compiler* instead? Yes. Sorry. Tired and brain functioning slower than usual snail pace. 5 minutes ago, Remy Lebeau said: Of course it can. Every Win32 API DLL can be, Microsoft ships both 32bit and 64bit versions of them. I have discovered that today. Because the because the compiler didn't recognise the unquoted reference to Shell32 I thought that the functions must have been re-packaged differently for 64 bit somehow (Shell64 or some such) . Anyway simply putting quote marks round Shell32 in my old function code worked fine. Live and learn. Share this post Link to post