don't know how to use IShellWindows::Item corr

2019-08-28 16:10发布

I'm using VC6 on XP system.

The following is my code. It runs perfectly on my computer, but on other computers it seems that pisw->Item(v, &pidisp) doesn't equals to S_OK. Now I'm trying to figure out what's wrong here

  IShellWindows *pisw;
  if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL,
                             IID_IShellWindows, (void**)&pisw))) {
  VARIANT v;
  V_VT(&v) = VT_I4;
  IDispatch  *pidisp;
  found = FALSE;

  for (V_I4(&v) = 0; !found && pisw->Item(v, &pidisp) == S_OK; V_I4(&v)++) {
     IWebBrowserApp *piwba;
    if (SUCCEEDED(pidisp->QueryInterface(IID_IWebBrowserApp, (void**)&piwba))) {
               //  blablabla....do something..
  }

So I changed some code to

...
IDispatch *pidisp;
hr = pisw->Item(v, &pidisp);
if (SUCCEEDED(hr))
{
      for (V_I4(&v) = 0; !found ; V_I4(&v)++) {
     IWebBrowserApp *piwba;
     if (SUCCEEDED(pidisp->QueryInterface(IID_IWebBrowserApp, (void**)&piwba))) {
               //  blablabla....do something..
   }

}

then the return value of hr becomes to 1. And it gets access violation errors when running to "pidisp->.." step. Can anyone help me?

2条回答
We Are One
2楼-- · 2019-08-28 16:39

The original code incorrectly tests the result of pisw->Item(v, &pidisp). Weird, because it does use the correct check later on.

The problem is that there are many success return values besides S_OK. Your fix is correct, you should use SUCCEEDED(hr), but you incorrectly moved the loop INSIDE the SUCCEEDED(hr) test. You should check SUCCEEDED(hr) for every value of V_I4(&v).

Your S_FALSE result is because you now call hr = pisw->Item(v, &pidisp); before the loop, which means v is uninitialized (garbage). Assume for a moment that its garbage value is 728365. S_FALSE means: the call succeeded, but there are less than 728365 windows.

查看更多
\"骚年 ilove
3楼-- · 2019-08-28 16:57

MSDN IShellWindows::Item:

Return value Type: HRESULT S_FALSE (1) The specified window was not found.

The item you are looking was not found, and you obviously don't get a valid pidisp. Trying to use it results - expectedly - in access violation.

You need to handle "item not found" case properly, and check your v argument as well.

查看更多
登录 后发表回答