Winapi SetValue和Release不是函数

Winapi SetValue和Release不是函数,winapi,firefox-addon,jsctypes,ipropertystorage,Winapi,Firefox Addon,Jsctypes,Ipropertystorage,总之:我搜索了MSDN,并想创建自己的SetValue,但找不到任何源代码。它不在DLL中,就像InitPropVariantFromString一样,它在头文件中,但我找不到它:如果你可以,请告诉我HTAT C++代码,我会从那里取:< /P> 最重要的是显示我在这方面的努力 这是我正在转换的微小C++代码: OnCreate(HWND hwnd, LPCREATESTRUCT lpcs) { IPropertyStore *pps; HRESULT hr = SHGetPropertyS

总之:我搜索了MSDN,并想创建自己的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, L"Contoso.Scratch");
 }
}
我将此翻译为:

  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());
此IPropertyStore_设置值是从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;
}
我想:

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;
}
因此,这需要我编写InitPropVariantFromString,我做到了:

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;                      
}
关于我的SHSTRDUP困境的一个小小的旁白并不是一个问题,只是表明我努力工作,通过无法解释的怪癖使它发挥了作用

因此,这需要我做一个我认为需要两个的SHStrDup ctypes.jschar.ptr的参数,因为它是LPCTSTR的第一个参数 和LPTSTR的第二个arg

对于第一个参数,我通过了recall的PCWSTR ctypes.jschar.array'Contoso.Scratch'。所以当我第一个arg 定义设置为ctypes.jschar.ptr它将无法使用它抛出 此错误:应为类型指针,已获取 ctypes.jschar.array16.ptrctypes.UInt640x2855b560

因此,我将定义从ctypes.jschar.ptr更改为 ctypes.voidptr\t在定义中,因此它适用于此参数 但随后在第二个参数上抛出了错误 propvarPtr.contents.pwszVal.address:

ctypes.jschar.ptr.ptrctypes.UInt640x20fdb3b4

然后我就把SHStrDup的两个参数都设置为 ctypes.voidptr_\t,它成功了。不知道为什么,但它起作用了。和 propvarPtr.contents.pwszVal肯定会被填充,因为 当I console.log时,它显示:propvarPtr.contents.pwszVal CData{ 目录:C}

最后的SHStrDup定义如下:

/* 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)
);
现在所有这些都通过了,我回到了IPropertyStore_SetValue中,如果:

  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,这就是它的作用,我不知道如何修复它


我搜索了MSDN,想创建自己的SetValue,但找不到任何源代码。它不在DLL中,就像InitPropVariantFromString一样,它在头文件中,但我找不到它:如果你能给我看一下HTAT C++代码,我会从那里得到:

解决,我必须使用VTBL:

Vtbl中定义的顺序在很大程度上是重要的。因此,如果您想使用Vtbls执行某些操作,请确保它是正确的

然后,要获取窗口的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.SetValueppsPtr、firstArgOf_SetValue、secondArgOf_SetValue

编辑: 从草稿行添加复制粘贴可运行脚本。 复制并粘贴以下内容:

这将相当于此XPCOM:

 var win = Services.wm.getMostRecentWindow(null);
 Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar).setGroupIdForWindow(win, 'Contoso.Scratch')

是的,但它的好处是,没有XPCOM来设置RelaunChand和RelauncIon资源等。这就是为什么需要JS cType。

Irc,你没有任何C++知识,如果你有,你会意识到你想做的是多么无用,但是无论如何,这里是感谢的定义,如此多的人!我会想办法的,伙计,否则我会找到别的办法!你能把这个作为解决办法吗。我想投赞成票,因为我花了很长时间找不到,我真的很感激。我交了一个思科的朋友,我要试着邀请他过来,给他沏茶和沙拉饼干,希望他能和我坐下来。当我陷入远程分配的困境时,他和我坐了下来。哈哈,但是我需要把一切都安排好,这样我们就可以坐下来休息几个小时了。否则我会和他在这里挣扎哈哈。非常感谢你,伙计。请转向解决方案。也是最坏的情况,我不能这样做,至少我们有一堆新的东西可以分享,作为例子,它可能会在某个地方帮助别人。也许我可以向ctypes请求新功能:P我是充满希望的人!:P@paa请参阅解决方案、粘贴库、复制粘贴到草稿行!跑吧上帝啊!!!我使用了你的链接来获取Vtbl中定义的顺序,因此你帮助发布该链接真的很有帮助!!:HARAR,在C++中用C++编写VC++ VTABLE PTR。很好。@nmaier:D:D:D我从这里提升了方法::D:Dhey@nmaier我编辑了主题,在hr行下面我添加了XPCOM的一个片段,然后是js ctypes的一个复制粘贴片段,你可以运行它,你会看到scratchpad窗口从当前组中被解组我还修改了vtbl定义顺序,因为这非常重要
 var win = Services.wm.getMostRecentWindow(null);
 Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar).setGroupIdForWindow(win, 'Contoso.Scratch')