[C++/ATL] browser control verschijnt op verkeerde plek

Pagina: 1
Acties:

  • MisterData
  • Registratie: September 2001
  • Laatst online: 27-11 20:42
Al een paar uur zit ik te stoeien met het embedden van een ActiveX-control (namelijk Shell.Explorer.2, de Internet Explorer control, en later misschien die van Mozilla). Het duurde me al twee uur om uit te vinden dat 'AtlAxWin' veranderd is in 'AtlAxWin80', maargoed :/ Ik gebruik dus onderstaand stukje code om zo'n control te maken:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
BrowserWnd::BrowserWnd(HWND parent): ChildWnd(L"", parent, true, false) {
    SetStyle(WS_CLIPCHILDREN);
    Layout();

    HINSTANCE inst = (HINSTANCE)GetWindowLong(_wnd, GWL_HINSTANCE);


    _bwnd = CreateWindowEx(0L, L"AtlAxWin80", L"Shell.Explorer.2", WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, 0, 0, 100, 100, _wnd, 0L, inst,0 );
    int e = GetLastError();
    if(_bwnd==0) {
        Log::Write(L"Browser/Wnd", L"failed: "+Stringify(e));
    }
}


Ik krijg netjes een HWND terug naar een AtlAxWin80 window in mijn eigen window. Het vreemde is echter dat de browser zelf, volgens Spy++ een window met class 'Shell Embedding', verschijnt in de linkerbovenhoek van mijn scherm en geen child is van de AtlAxWin80 of mijn eigen window... hoe los ik dit op?

Ik weet niet of het uitmaakt: AtlAxWinInit wordt netjes aangeroepen en werkt prima, de code bevindt zich in een DLL, maar doet in DllMain netjes de CComModule initialiseren. De superclass van BrowserWnd doet een CreateWindow en de HWND daarvan wordt in _wnd gezet, die ik dus als parent class voor de AtlAxWin80 gebruik.

Ook vreemd: met MSCAL.Calendar als class en bijvoorbeeld de mozilla CLSID krijg ik van GetLastError een 1400 ('invalid window handle')... zit toch ergens iets niet lekker in ATL?

Nog wat extra info: zelfs met CAxWindow (de ATL wrapper om AtlAxWin heen) werkt het niet goed. Hier een screenshot:

Afbeeldingslocatie: http://dev.mycms.nl/atlprobleem.png

[ Voor 9% gewijzigd door MisterData op 15-08-2006 18:11 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 27-11 20:42
Na lang zoeken blijkt het probleem te zitten in threading; omdat mijn applicatie multi-threaded is (en er threads zijn die onder andere multithreaded gebruik maken van DirectShow) werd COM geinitialiseerd met COINIT_MULTITHREADED. Dat leverde at runtime een RPC_E_CANTCALLOUT_ININPUTSYNCCALL fout op, blijkbaar veroorzaakt ergens in ATL. Nu ik COINIT_APARTMENTTHREADED gebruik werkt het allemaal wel (nu nog even kijken hoe het DirectShow-onderdeel zich gedraagt.... :/)

C++:
1
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

Verwijderd

Hi,

ik gebruik ook de class "AtlAxWin80" om een IWebBrowser2 te maken in een nieuwe window.

In m'n callback :
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static CComQIPtr<IWebBrowser2> pWB2;  
static HWND hwndIE;  
//static CComPtr<IUnknown> punkIE;  

    switch (mes)
    {
        case WM_CREATE :
        {
              
  
hwndIE = CreateWindow("AtlAxWin80",  
  
"http://www.apple.com", WS_CHILD|WS_VISIBLE|WS_TABSTOP, 0,0, 640, 480,hWnd, (HMENU)0, GetModuleHandle(NULL), NULL);  
return 0;
}
        case WM_DESTROY :
        {
            pWB2.Release();  
            DestroyWindow(hwndIE);
            UnregisterClass("AtlAxWin80",GetModuleHandle(NULL));
            PostQuitMessage(0);  

            return 0;  
        }


de starter:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
static char szAppName[] = "IWebBrowser2";  
  
HWND hwnd;  
  
MSG msg;  
 
AtlAxWinInit();  
   
WNDCLASSEX wndclass;  
  
wndclass.cbSize = sizeof(wndclass);  
  
wndclass.style = CS_HREDRAW | CS_VREDRAW;  
  
wndclass.lpfnWndProc = PopCallback;  
  
wndclass.cbClsExtra = 0;  
  
wndclass.cbWndExtra = 0;  
  
wndclass.hInstance = hInstance;  
  
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  
  
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);  
  
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  
  
wndclass.lpszMenuName = NULL;  
  
wndclass.lpszClassName = szAppName;  
  
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);  
  
RegisterClassEx(&wndclass);  
  
hwnd = CreateWindow(szAppName, "EigenBrowser", WS_OVERLAPPEDWINDOW,  
  
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,  
  
NULL, NULL, hInstance, NULL);


ShowWindow(hwnd, SW_SHOW);  
UpdateWindow(hwnd);  
  
while (GetMessage(&msg, NULL, 0, 0))  
  
{  
    TranslateMessage(&msg);  
    DispatchMessage(&msg);  
}  


_Module.Term();  
UnregisterClass("AtlAxWin80",GetModuleHandle(NULL));
UnregisterClass(szAppName,hInstance);
DWORD test;
test=GetLastError(); // is 0 hier
while(1){
   Sleep(1000); // een paar threads sluiten af na een paar minuten, zet hier je breakpoint
}
return (int)msg.wParam;  



Na onderzoek blijkt dat er OLE threads actief blijven terwijl ik elke interface stuk voor stuk bekeken heb en automatisch delete zijn door release.


Waarom doet IE zo stom???

in m'n output zie ik alleen deze dll's die niet automatisch geunload worden bij het afsluiten van m'n window:

'Example.exe': Loaded 'C:\WINDOWS\system32\msacm32.drv', No symbols loaded.
'Example.exe': Loaded 'C:\WINDOWS\system32\msacm32.dll', No symbols loaded.
'Example.exe': Loaded 'C:\WINDOWS\system32\midimap.dll', No symbols loaded.
'Example.exe': Loaded 'C:\WINDOWS\system32\setupapi.dll', No symbols loaded.


uhm... now we wait??? 7(8)7