SetValue和Release不是函数 [英] SetValue and Release are not functions
问题描述
SetValue
,但我找不到任何源代码。它不在一个DLL中,它像 InitPropVariantFromString
,它在一个头文件中,但是我找不到它。 :(如果你可以请只显示我htat C ++代码,我会从那里拿):底部的东西是显示我所做的努力。 p>
这是我转换的小C ++代码:
OnCreate(HWND hwnd,LPCREATESTRUCT lpcs)
{
IPropertyStore * pps;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd,IID_PPV_ARGS(& pps));
if(SUCCEEDED(hr)){
IPropertyStore_SetValue(pps,PKEY_AppUserModel_ID,LContoso.Scratch);
$ / code $ / pre
我已经把它翻译成了:var ppv = ctypes.voidptr_t(0);
var pps = new IID();
var HR_pps = CLSIDFromString('{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}',pps.address());
if(!checkHRESULT(HR_pps)){throw new Error('checkHRESULT error'); }
var hr = SHGetPropertyStoreForWindow(hwnd,pps.address(),ppv.address());
if(!checkHRESULT(hr)){throw new Error('checkHRESULT error'); }
var pszValue = ctypes.jschar.array()('Contoso.Scratch'); // PCWSTR
IPropertyStore_SetValue(pps.address(),PKEY_AppUserModel_ID,pszValue.address());
从这个C ++转换而来的
IPropertyStore_SetValue
$ b $ pre $HRESULT IPropertyStore_SetValue(IPropertyStore * pps,REFPROPERTYKEY pkey,PCWSTR pszValue)
{
PROPVARIANT var;
HRESULT hr = InitPropVariantFromString(pszValue,& var);
if(SUCCEEDED(hr)){
hr = pps-> SetValue(pkey,var);
PropVariantClear(& var);
}
return hr;
$ / code>
我得到了:
var struct_PROPVARIANT = ctypes.StructType('PROPVARIANT',[
{'fntud':struct_GUID},// GUID
{'pid':ctypes .unsigned_long},// DWORD
//从loomo注释union :: union不被js-ctypes支持https://bugzilla.mozilla.org/show_bug.cgi?id=535378你总是可以指派类型指针,至少只要你知道哪个类型是最大的
//所以现在在我的情况下,我知道InitPropVariantFromString正在寻找pwszVal,所以忘记所有其他的联盟废话,只是离开这个
{'pwszVal':new ctypes.PointerType(ctypes.jschar)} // LPWSTR
]);
var IPropertyStore_SetValue =函数(pps / ** IPopertyStore指针** /,pkey / ** PROPERTYKEY ** /,pszValue / ** PCWSTR ** /){
var v = new struct_PROPVARIANT(); // PROPVARIANT
var rez = InitPropVariantFromString(pszValue,v.address());
if(rez){
console.info('pps.SetValue',pps.SetValue);
pps.SetValue(pkey,v);
} else {
throw new Error('failed InitPropVariantFromString');
}
返回true;
$ b 所以这需要我写 InitPropVariantFromString
$ p $函数InitPropVariantFromString(string / ** PCWSTR ** /,propvarPtr / ** PROPVARIANT指针** /){
var hr = SHStrDup(string,propvarPtr.contents.pwszVal.address());
if(!checkHRESULT(hr)){
// PropVariantInit(propvarPtr); //可以跳过这个,它只是一个memset
}
返回true;
$ b $ hr
$ b
对我的SHSTRDUP DILEMMA的一个小小的内容(不是一个问题,只是表明我努力工作,通过无法解释的怪异才得以实现)
所以这需要我做 SHStrDup
,我认为这需要两个
参数 ctypes.jschar.ptr
,因为它是 LPCTSTR
和 LPTSTR
的第二个参数。 / p>
对于第一个参数,我传递了召回
ctypes.jschar.array()('Contoso.Scratch')的PCWSTR。
。所以当我把第一个arg
定义设置为 ctypes.jschar.ptr
时,它不会使用它抛出
这个错误:预期类型指针,得到
ctypes.jschar.array(16).ptr(ctypes.UInt64(0x2855b560))
所以我把定义从 ctypes.jschar.ptr
更改为
ctypes.voidptr_t
in defintion所以然后它为这个参数
工作,但随后抛出第二个参数错误记得
propvarPtr.contents.pwszVal.address()
: ctypes.jschar.ptr.ptr(ctypes.UInt64(0x20fdb3b4))
,
所以我最后把 SHStrDup
这两个参数设置为
ctypes.voidptr_t
,它工作。不知道为什么,但它的工作。和
propvarPtr.contents.pwszVal
肯定会被填充,因为
当我console.log它显示:propvarPtr .contents.pwszValCData {
contents:C}
。
所以最后 SHStrDup defintion看起来像这样:
/ * http://msdn.microsoft.com/en- us / library / windows / desktop / bb759924%28v = vs.85%29.aspx
* HRESULT SHStrDup(
* __in_ LPCTSTR pszSource,
* __out_ LPTSTR * ppwsz
* );
* /
var SHStrDup = shlwapi.declare('SHStrDupW',ctypes.winapi_abi,ctypes.long,// HRESULT
ctypes.voidptr_t,// LPCTSTR //应该是ctypes.jschar .ptr or ctypes.char.ptr //我试图在这里传递PCWSTR,它是`ctypes.jschar.array()('blah blah')。address()`
ctypes.voidptr_t // LPTSTR //应该是ctypes.jschar.ptr或ctypes.char.ptr / / im试图传递地址struct_PROPVARIANT.pwszVal这是新的ctypes.PointerType(ctypes.jschar)
);
所有的传递,我最终回到 IPropertyStore_SetValue
在这个if:
var rez = InitPropVariantFromString(pszValue,v.address());
if(rez){
console.info('pps.SetValue',pps.SetValue);
pps.SetValue(pkey,v);
} else {
throw new Error('failed InitPropVariantFromString');
现在 rez
是真正的,所以它现在尝试 pps.SetValue
这是它去的地方,我不知道如何解决它。 :(b / b)
我搜索了MSDN,想创建自己的 SetValue
,但是我找不到任何源代码。它不在一个DLL中,它像 InitPropVariantFromString
,它在一个头文件中,但是我找不到它。:(如果你可以请告诉我一下htat C ++代码我会从这里拿:)解决方案,我不得不使用VTBL:解决方案
/github.com/Noitidart/_scratchpad/blob/master/IPropertyStore%20COM%20jsctypes.jsrel =nofollow> https://github.com/Noitidart/_scratchpad/blob/master/IPropertyStore%20COM%20jsctypes.js
Vtbl
中定义的顺序很重要,所以请确保它的正确性你想用 Vtbl
s var IPropertyStoreVtbl = new ctypes .StructType('IPropertyStoreVtbl');
var IPropertyStore = new ctypes.StructType('IPropertyStore',[{
'lpVtbl':IPropertyStoreVtbl.ptr
} ]);
this.IPropertyStorePtr = new ctypes.PointerType(IPropertyStore);
IPropertyStoreVtbl.define(
[{//开始从IUnknown继承$ b $'QueryInterface':ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT,[
IPropertyStore.ptr,
this.REFIID,// riid
this.VOIDPTR // ** ppvObject
])。ptr
},{
' AddRef':ctypes.FunctionType(ctypes.stdcall_abi,
this.ULONG,[
IPropertyStore.ptr
])。ptr
},{
'Release': ctypes.FunctionType(ctypes.stdcall_abi,
this.ULONG,[
IPropertyStore.ptr
])。ptr
},{//结束继承自IUnknown //启动IPropertyStore
'GetCount':ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT,[
IPropertyStore.ptr,
this.DWORD.ptr // * cProps
] ).ptr
},{
'GetAt':ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT,[
IPropertyStore.ptr,
this.DWORD,// iProp
this.PROPERTYKEY.ptr ptr
},{
'GetValue':ctypes.FunctionType(ctypes.stdcall_abi,$ b $ this.HRESULT,[
IPropertyStore。 ptr,
this.REFPROPERTYKEY,// key
this.PROPVARIANT.ptr // * pv
])。ptr
},{
'SetValue':ctypes .FunctionType(ctypes.stdcall_abi,
this.HRESULT,[
IPropertyStore.ptr,
this.REFPROPERTYKEY,// key
this.REFPROPVARIANT // propvar
] ).ptr
},{
'Commit':ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT,[
IPropertyStore.ptr
])。ptr
}]
);
然后获取窗口的 IPropertyStore
:
var ppsPtr = new ostypes.IPropertyStorePtr();
var hr_SHGetPropertyStoreForWindow = _dec('SHGetPropertyStoreForWindow')(cHwnd,IID_IPropertyStore.address(),ppsPtr.address());
checkHRESULT(hr_SHGetPropertyStoreForWindow,'SHGetPropertyStoreForWindow');
var pps = ppsPtr.contents.lpVtbl.contents;现在你可以使用 IPropertyStore :: SetValue
和 IPropertyStore :: Release
但确保将 ppsPtr
作为第一个参数传递给它们,然后剩下的参数就是你会期望: var hr = pps.SetValue(ppsPtr,firstArgOf_SetValue,secondArgOf_SetValue)
编辑:
从暂存区添加复制粘贴可运行脚本。
复制并粘贴: http://pastebin.mozilla.org/8429999
这将完成相当于这个XPCOM:
var win = Services。 wm.getMostRecentWindow(NULL);
Cc [@ mozilla.org/windows-taskbar;1\"].getService(Ci.nsIWinTaskbar).setGroupIdForWindow(win,'Contoso.Scratch')
是的,但它的好处是,没有XPCOM设置 RelaunchCommand
和 RelaunchIconResource
等,这就是为什么js-ctypes是必要的。
In summary: I searched MSDN and thought to create my own SetValue
but I can't find any sourcecode for it. It's not in a DLL, its like InitPropVariantFromString
, it's in a header file, but I can't find it. :( If you can please just show me htat C++ code I'll take it from there :)
Bottom stuff is to show the efforts I put on it.
This is the tiny C++ code I'm converting:
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
IPropertyStore *pps;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr)) {
IPropertyStore_SetValue(pps, PKEY_AppUserModel_ID, L"Contoso.Scratch");
}
}
I have translated this to:
var ppv = ctypes.voidptr_t(0);
var pps = new IID();
var HR_pps = CLSIDFromString('{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}', pps.address());
if (!checkHRESULT(HR_pps)) { throw new Error('checkHRESULT error'); }
var hr = SHGetPropertyStoreForWindow(hwnd, pps.address(), ppv.address());
if (!checkHRESULT(hr)) { throw new Error('checkHRESULT error'); }
var pszValue = ctypes.jschar.array()('Contoso.Scratch'); // PCWSTR
IPropertyStore_SetValue(pps.address(), PKEY_AppUserModel_ID, pszValue.address());
This IPropertyStore_SetValue
I converted from this C++:
HRESULT IPropertyStore_SetValue(IPropertyStore *pps, REFPROPERTYKEY pkey, PCWSTR pszValue)
{
PROPVARIANT var;
HRESULT hr = InitPropVariantFromString(pszValue, &var);
if (SUCCEEDED(hr)) {
hr = pps->SetValue(pkey, var);
PropVariantClear(&var);
}
return hr;
}
I got it to:
var struct_PROPVARIANT = ctypes.StructType('PROPVARIANT', [
{'fntud': struct_GUID}, // GUID
{'pid': ctypes.unsigned_long}, // DWORD
// comment from loomo on union :: union not supported by js-ctypes https://bugzilla.mozilla.org/show_bug.cgi?id=535378 "You can always typecast pointers, at least as long as you know which type is the biggest"
// so now in my case i know that InitPropVariantFromString is looking to se the pwszVal so forget all the other crap in the union and just leave this one
{'pwszVal': new ctypes.PointerType(ctypes.jschar)} // LPWSTR
]);
var IPropertyStore_SetValue = function(pps /** IPopertyStore pointer **/, pkey /** PROPERTYKEY **/, pszValue /** PCWSTR **/) {
var v = new struct_PROPVARIANT(); // PROPVARIANT
var rez = InitPropVariantFromString(pszValue, v.address());
if (rez) {
console.info('pps.SetValue', pps.SetValue);
pps.SetValue(pkey, v);
} else {
throw new Error('failed InitPropVariantFromString');
}
return true;
}
So this required me to write InitPropVariantFromString
which I did:
function InitPropVariantFromString(string /** PCWSTR **/, propvarPtr /** PROPVARIANT pointer **/) {
var hr = SHStrDup(string, propvarPtr.contents.pwszVal.address());
if (!checkHRESULT(hr)) {
//PropVariantInit(propvarPtr); //can skip this, it just does a memset
}
return true;
}
A SMALL ASIDE ON MY SHSTRDUP DILEMMA (not a question just showing i worked hard and through unexplainable weirdness got it to work)
So this required me to do SHStrDup
which I thought would take two
arguments of ctypes.jschar.ptr
as it is first argument of LPCTSTR
and second arg of LPTSTR
.
For the first argument, i was passing the PCWSTR of recall
ctypes.jschar.array()('Contoso.Scratch')
. So when I the first arg
definition set to ctypes.jschar.ptr
it wouldn't work use it throws
this error: expected type pointer, got
ctypes.jschar.array(16).ptr(ctypes.UInt64("0x2855b560"))
So I change in the defintion from ctypes.jschar.ptr
to
ctypes.voidptr_t
in defintion so then it worked for this argument
but then threw error on second argument recall the
propvarPtr.contents.pwszVal.address()
:
ctypes.jschar.ptr.ptr(ctypes.UInt64("0x20fdb3b4"))
,
So then I just ended up setting both arguments of SHStrDup
to
ctypes.voidptr_t
and it worked. Don't know why but it worked. And
propvarPtr.contents.pwszVal
is definitely getting populated, because
when I console.log it it shows: "propvarPtr.contents.pwszVal" CData {
contents: "C" }
.
So the final SHStrDup
defintion looked like this:
/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb759924%28v=vs.85%29.aspx
* HRESULT SHStrDup(
* __in_ LPCTSTR pszSource,
* __out_ LPTSTR *ppwsz
* );
*/
var SHStrDup = shlwapi.declare('SHStrDupW', ctypes.winapi_abi, ctypes.long, // HRESULT
ctypes.voidptr_t, // LPCTSTR // should be ctypes.jschar.ptr OR ctypes.char.ptr // im trying to pass PCWSTR here, which is `ctypes.jschar.array()('blah blah').address()`
ctypes.voidptr_t // LPTSTR // should be ctypes.jschar.ptr OR ctypes.char.ptr // im trying to pass address to struct_PROPVARIANT.pwszVal which is new ctypes.PointerType(ctypes.jschar)
);
So now all that is passing and I end up back in IPropertyStore_SetValue
in this if:
var rez = InitPropVariantFromString(pszValue, v.address());
if (rez) {
console.info('pps.SetValue', pps.SetValue);
pps.SetValue(pkey, v);
} else {
throw new Error('failed InitPropVariantFromString');
}
Now rez
is true, so then it now tries pps.SetValue
and this is where it goes kaput and I can't figure out how to fix it. :(
I searched MSDN and thought to create my own SetValue
but I can't find any sourcecode for it. It's not in a DLL, its like InitPropVariantFromString
, it's in a header file, but I can't find it. :( If you can please just show me htat C++ code I'll take it from there :)
解决方案 Solved, I had to use VTBL: https://github.com/Noitidart/_scratchpad/blob/master/IPropertyStore%20COM%20jsctypes.js
The order of the defintions in the Vtbl
matter big time. So make sure its correct if you want to do something with Vtbl
s
var IPropertyStoreVtbl = new ctypes.StructType('IPropertyStoreVtbl');
var IPropertyStore = new ctypes.StructType('IPropertyStore', [{
'lpVtbl': IPropertyStoreVtbl.ptr
}]);
this.IPropertyStorePtr = new ctypes.PointerType(IPropertyStore);
IPropertyStoreVtbl.define(
[{ //start inherit from IUnknown
'QueryInterface': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFIID, // riid
this.VOIDPTR // **ppvObject
]).ptr
}, {
'AddRef': ctypes.FunctionType(ctypes.stdcall_abi,
this.ULONG, [
IPropertyStore.ptr
]).ptr
}, {
'Release': ctypes.FunctionType(ctypes.stdcall_abi,
this.ULONG, [
IPropertyStore.ptr
]).ptr
}, { //end inherit from IUnknown //start IPropertyStore
'GetCount': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.DWORD.ptr // *cProps
]).ptr
}, {
'GetAt': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.DWORD, // iProp
this.PROPERTYKEY.ptr //*pkey
]).ptr
}, {
'GetValue': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFPROPERTYKEY, // key
this.PROPVARIANT.ptr // *pv
]).ptr
}, {
'SetValue': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFPROPERTYKEY, // key
this.REFPROPVARIANT // propvar
]).ptr
}, {
'Commit': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr
]).ptr
}]
);
Then to get the IPropertyStore
of a window:
var ppsPtr = new ostypes.IPropertyStorePtr();
var hr_SHGetPropertyStoreForWindow = _dec('SHGetPropertyStoreForWindow')(cHwnd, IID_IPropertyStore.address(), ppsPtr.address());
checkHRESULT(hr_SHGetPropertyStoreForWindow, 'SHGetPropertyStoreForWindow');
var pps = ppsPtr.contents.lpVtbl.contents;
now you can use IPropertyStore :: SetValue
and IPropertyStore :: Release
but make sure to pass the ppsPtr
as first argument to them then the remaining arguments are what you would expect: var hr = pps.SetValue(ppsPtr, firstArgOf_SetValue, secondArgOf_SetValue)
EDIT:
adding copy paste runnable script from scratchpad.
Copy and paste this: http://pastebin.mozilla.org/8429999
this will do the equivalent of this XPCOM:
var win = Services.wm.getMostRecentWindow(null);
Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar).setGroupIdForWindow(win, 'Contoso.Scratch')
Yes its long but the good thing about it is, there is no XPCOM to set RelaunchCommand
and RelaunchIconResource
etc. Thats why js-ctypes is needed.
这篇关于SetValue和Release不是函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!