Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting a selected file or folder #1340

Open
amtopel opened this issue May 12, 2019 · 8 comments
Open

Getting a selected file or folder #1340

amtopel opened this issue May 12, 2019 · 8 comments

Comments

@amtopel
Copy link

amtopel commented May 12, 2019

Would it be possible to add support for getting a selected file or folder? I understand that the Windows API has GetFocusedItem, but I'm not aware of that within pywin. Thank you very much for your time.

@mhammond
Copy link
Owner

What API specifically are you talking about?

@amtopel
Copy link
Author

amtopel commented May 13, 2019

I believe it's IFolderView::GetFocusedItem, documented here: https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-ifolderview-getfocuseditem

@smourier
Copy link

pywin32 doesn't currently define IFolderView

This is used for various Shell scenarios, for example: Manipulating the positions of desktop icons

I can try to add it and do a pull request if you're interested?

@mhammond
Copy link
Owner

Sure, I'd welcome a good patch which adds support for IFolderView

@smourier
Copy link

Hi, sorry for the long post!

I have quite a number of issues with makegw, especially makegwparse.py. It seems this system doesn't support .h files from the more relatively recent Windows SDK. I'm using this code:

import sys
sys.path.insert(0, 'D:\\GitHub\\pywin32\\com\\win32com')

import makegw.makegw
makegw.makegw.make_framework_support("C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.17763.0\\um\\shobjidl_core.h", "IFolderView")
makegw.makegw.make_framework_support("C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.17763.0\\um\\shobjidl_core.h", "IFolderView2")

Some issues:

        virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems( 
            /* [in] */ UINT cidl,
            /* [size_is][in] */ __RPC__in_ecount_full(cidl) PCUITEMID_CHILD_ARRAY apidl,
            /* [size_is][unique][in][disable_consistency_check] */ __RPC__in_ecount_full_opt(cidl) POINT *apt,
            /* [in] */ DWORD dwFlags) = 0;

  • I also retried with IShellView (that is already coded in pywin32) to compare, and multiline arguments like where the intermediary remark don't match current regexes, nor the double space between In and DWORD:
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE AddPropertySheetPages( 
            /* [annotation][in] */ 
            _In_  DWORD dwReserved,
            /* [annotation][in] */ 
            _In_  LPFNSVADDPROPSHEETPAGE pfn,
            /* [annotation][in] */ 
            _In_  LPARAM lparam) = 0;
  • pointer types (like void**) doesn't seem to be recognized although they are defined as specific. For example this input:

      virtual HRESULT STDMETHODCALLTYPE GetFolder( 
          /* [in] */ __RPC__in REFIID riid,
          /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
    

is generated into this ("void ppv", "PyObject_Asvoid", "PyObject_Freevoid(ppv)"):

// @pymethod |PyIFolderView|GetFolder|Description of GetFolder.
PyObject *PyIFolderView::GetFolder(PyObject *self, PyObject *args)
{
	IFolderView *pIFV = GetI(self);
	if ( pIFV == NULL )
		return NULL;
	// @pyparm <o PyIID>|riid||Description for riid
// *** The input argument ppv of type "__RPC__deref_out_opt void **" was not processed ***
//     Please check the conversion function is appropriate and exists!
	void ppv;
	PyObject *obppv;
	// @pyparm <o Pyvoid>|ppv||Description for ppv
	PyObject *obriid;
	IID riid;
	if ( !PyArg_ParseTuple(args, "OO:GetFolder", &obriid, &obppv) )
		return NULL;
	BOOL bPythonIsHappy = TRUE;
	if (!PyWinObject_AsIID(obriid, &riid)) bPythonIsHappy = FALSE;
	if (bPythonIsHappy && !PyObject_Asvoid( obppv, &ppv )) bPythonIsHappy = FALSE;
	if (!bPythonIsHappy) return NULL;
	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIFV->GetFolder( riid, ppv );
	PyObject_Freevoid(ppv);

	PY_INTERFACE_POSTCALL;

	if ( FAILED(hr) )
		return PyCom_BuildPyException(hr, pIFV, IID_IFolderView );
// *** The output argument ppv of type "__RPC__deref_out_opt void **" was not processed ***
//     The type 'void' (ppv) is unknown.
	Py_INCREF(Py_None);
	return Py_None;

}

I've fixed the SAL issue, adding feature to makegwparse.py (see below) but while I'm progressing, I face other issues. So, I would like to know your thinking about this:

  • Should try to modifymakegw.py makegwparse.pyto handle newer constructs but I'm afraid it could break things.
  • Should I just go ahead and use them as is and fix the resulting PyIFolderView.cpp by hand? Note it still would be mean to add some newer argument conversion function too since some arguments are not yet known by shell.cpp.

Thanks!

For information here's the code I've added to for parsing SAL which I currently only use to determine the real type name:

class Annotation:
    def __init__(self):
        self.sal = None # the full annotation as a string
        self.type = None # the result type w/o annotation
        self.args = None # an array of arguments if any
        self.components = None # an array of components of the annotation

    def Parse(self, text):
        # see https://docs.microsoft.com/en-us/windows/win32/winprog/header-annotations
        self.type = text
        paren = text.find("(")
        if (paren >= 0):
            self.sal = text[:paren].strip()
            print(self.sal)
            endparen = text.find(")", paren + 1)
            if (endparen > paren):
                self.type = text[endparen + 1:].strip()
                self.args = text[paren + 1:endparen -1].strip().split(",")
                
        else:
            space = text.find(" ")
            if (space >= 0):
                self.sal = text[:space].strip()
                self.type = text[space:].strip()

        if self.sal:
            self.components = list(filter(lambda c: c != "", self.sal.split("_")))
        
        return;

    def __repr__(self):
        return f'Annotation(type={self.type}, sal={self.sal}, args={self.args}, components={self.components})'

@mhammond
Copy link
Owner

mhammond commented Apr 21, 2022 via email

@CristiFati
Copy link
Contributor

CristiFati commented Nov 10, 2024

Mentioning #2181, which I believe fixes this.

@Avasam
Copy link
Collaborator

Avasam commented Nov 11, 2024

@amtopel & @smourier Could you try with pywin32>=307 ? At a glance it does look like support was added in #2181

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants