2013-10-11 4 views
1

코드 (http://msdn.microsoft.com/en-us/library/windows/desktop/ff625913(v=vs.85).aspx#FindByName)를 다시 사용하려고했지만 간단한 클래스로 포장하고 싶습니다. 이 코드를 실행하면 다음 코드와 같습니다 :UI 자동화 CreatePropertyCondition 0xc0000005

hr = g_pAutomation->CreatePropertyCondition(UIA_ClassNamePropertyId, varProp, &pCondition); 

0xc0000005

나는 빈 또는 깨진 포인터 때문에 그것을 알고있다. 그러나 어떤 코드도없이이 코드를 실행하면 (main()) 완벽하게 작동합니다.

왜 내가 읽고 왜 이해해야 하는가?

#pragma once 

#include <UIAutomation.h> 

class Automator 
{ 
protected: 
    IUIAutomation* g_pAutomation; 
    IUIAutomationElement* pRoot; 
    IUIAutomationElementArray* pArrFound; 
    IUIAutomationElement* pFound; 
public: 
    Automator(void); 
    ~Automator(void); 
    void ClearResources(void); 
    void FindAllWindows(void); 
}; 


#include "Automator.h" 

Automator::Automator(void) 
{ 
    pRoot = NULL; 
    pArrFound = NULL; 
    pFound = NULL; 
    g_pAutomation = NULL; 

    CoInitialize(NULL); 
    HRESULT hr; 
    hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, 
      __uuidof(IUIAutomation), (void**)&g_pAutomation); 
    if(FAILED(hr)) 
      ClearResources(); 
    else 
    { 
      hr = g_pAutomation->GetRootElement(&pRoot); 
      if (FAILED(hr) || pRoot == NULL) 
      ClearResources(); 
    } 

} 

Automator::~Automator(void) 
{ 
    ClearResources(); 
} 

// 
//Doesn't work 
// 
void Automator::FindAllWindows(void) 
{ 
    VARIANT varProp; 
    varProp.vt = VT_BSTR; 
    varProp.bstrVal = L""; 

    IUIAutomationCondition* pCondition; 
    HRESULT hr = NULL; 
    if (g_pAutomation != NULL) 
    { 
     hr = g_pAutomation->CreatePropertyCondition(UIA_ClassNamePropertyId, varProp,  &pCondition); 
     if(FAILED(hr)) 
     { 
       if (pCondition != NULL) 
        pCondition->Release(); 
       ClearResources(); 
     } 
     else 
     { 
       pRoot->FindAll(TreeScope_Subtree, pCondition, &pArrFound); 
     } 
    } 

    if(pCondition != NULL) 
     pCondition->Release(); 
} 

void Automator::ClearResources(void) 
{ 
    if (pRoot != NULL) 
     pRoot->Release(); 

    if (pArrFound != NULL) 
     pArrFound->Release(); 

    if (pFound != NULL) 
     pFound->Release(); 

    if (g_pAutomation != NULL) 
     g_pAutomation->Release(); 

    CoUninitialize(); 
} 

답변

0

내가 문제의 몇 가지를 참조하십시오

  1. 클래스 생성자/소멸자에서으로 CoInitialize/CoUninitialize를 호출하지 마십시오; main (또는 스레드 진입 점)에서 처리하십시오. main()이 호출되기 전에 상당한 양의 코드가 실행되고 (이 경우 정적 클래스 초기화 프로그램) main() 외부로 실행하면 문제가 발생할 수 있습니다.
  2. main()을 표시하지 않았습니다. Automator 개체는 어디에 생성하고 있습니까? 실제로 당신이 Automator을 만들지 않았다고 의심합니다. 그것이 충돌합니다.

것은 내가 당신의 main을 쓰려고한다면, 그것은 다음과 같을 것이다 :

_wmain(int argc, wchar_t **argv) 
{ 
    CoInitialize(); 
    { 
     Automator automator; 
     automator.FindAllWindows(); 
    } 
    CoUninitialize(); 
} 

여분의 범위 브래킷이 보장하는 것입니다 CoUninitialize 전에 자동화 소멸자 실행().