質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2806閲覧

C++ で起動済みの IE の URL を列挙するソースについての疑問点

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/07/10 09:02

以下サイトを参考に、後述のプログラムを作成しました。
https://www.usefullcode.net/2006/12/ieihtmldocument2.html

プログラムは正常に動作しているのですが、
後続の疑問点が解消できない為、
ご存じの方がおりましたら、ご回答をお願いいたします。

言語:C++
環境:Windows10 64bit / Visual Studio 2019

作成したプログラム

C++

1#include <atlstr.h> 2#include <exdisp.h> 3#include <mshtml.h> 4 5bool GetHTMLDocument2FromHWND(HWND hWnd, IHTMLDocument2** ppIHTMLDocument2, bool bHwndIsServer = true) 6{ 7 HINSTANCE hInst; 8 LRESULT lRes; 9 UINT nMsg; 10 LRESULT ret; 11 12 LPFNOBJECTFROMLRESULT pfObjectFromLresult; 13 14 if (ppIHTMLDocument2 == NULL || hWnd == NULL || IsWindow(hWnd) == FALSE) 15 return false; 16 17 if (bHwndIsServer == false) 18 { 19 hWnd = FindWindowEx(hWnd, NULL, _T("Internet Explorer_Server"), NULL); 20 if (hWnd == NULL) 21 return false; 22 } 23 24 hInst = LoadLibrary(_T("OLEACC.DLL")); 25 if (hInst == NULL) 26 return false; 27 28 nMsg = RegisterWindowMessage(_T("WM_HTML_GETOBJECT")); 29 ret = SendMessageTimeout(hWnd, nMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes); 30 if (ret == 0) 31 return false; 32 33 pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)GetProcAddress(hInst, "ObjectFromLresult"); 34 if (pfObjectFromLresult) 35 (*pfObjectFromLresult)(lRes, IID_IHTMLDocument2, 0, (void**)ppIHTMLDocument2); 36 37 FreeLibrary(hInst); 38 39 return *ppIHTMLDocument2 ? true : false; 40} 41 42class CDnpEnumInternetExplore 43{ 44 // EnumWindowsのコールバック関数 45 static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 46 { 47 int nRet; 48 TCHAR pszName[1024]; 49 50 nRet = GetClassName(hwnd, pszName, sizeof(pszName)); 51 if (nRet == 0) 52 return TRUE; 53 54 nRet = _tcscmp(pszName, _T("IEFrame")); 55 if (nRet != 0) 56 return TRUE; 57 58 EnumChildWindows(hwnd, EnumChildProc, (LPARAM)NULL); 59 60 return TRUE; 61 } 62 63 // EnumChildWindowsのコールバック関数 64 static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) 65 { 66 int nRet; 67 bool ret; 68 HRESULT hr; 69 BSTR bstrURL; 70 TCHAR pszName[1024]; 71 IHTMLDocument2* pIHTMLDocument2; 72 73 nRet = GetClassName(hwnd, pszName, sizeof(pszName)); 74 if (nRet == 0) 75 return TRUE; 76 77 nRet = _tcscmp(pszName, _T("Internet Explorer_Server")); 78 if (nRet != 0) 79 return TRUE; 80 81 pIHTMLDocument2 = NULL; 82 ret = GetHTMLDocument2FromHWND(hwnd, &pIHTMLDocument2); 83 if (ret == false || pIHTMLDocument2 == NULL) 84 return TRUE; 85 86 bstrURL = NULL; 87 hr = pIHTMLDocument2->get_URL(&bstrURL); 88 if (SUCCEEDED(hr)) 89 { 90 CAtlString strURL; 91 92 strURL = (WCHAR*)bstrURL; 93 SysFreeString(bstrURL); 94 95 printf("%ws\n", strURL); 96 } 97 98 pIHTMLDocument2->Release(); 99 100 return TRUE; 101 } 102 103public: 104 void EnumStart() 105 { 106 BOOL ret; 107 ret = EnumWindows(EnumWindowsProc, (LPARAM)NULL); 108 } 109}; 110 111void main() 112{ 113 CoInitialize(NULL); 114 115 CDnpEnumInternetExplore cEnum; 116 117 cEnum.EnumStart(); 118 119 CoUninitialize(); 120}

疑問点その1

ObjectFromLresult を LoadLibrary(_T"OLEACC.DLL") を用いて使用している点について疑問に思いました。
ObjectFromLresult は oleacc.h で宣言されています。
なので、#include <oleacc.h> からでも利用できるのでは?と思い、実際にやってみました。

修正後のプログラム(GetHTMLDocument2FromHWND のみ)

C++

1#include <oleacc.h> 2 3bool GetHTMLDocument2FromHWND(HWND hWnd, IHTMLDocument2** ppIHTMLDocument2, bool bHwndIsServer = true) 4{ 5 LRESULT lRes; 6 UINT nMsg; 7 LRESULT ret; 8 9 if (ppIHTMLDocument2 == NULL || hWnd == NULL || IsWindow(hWnd) == FALSE) 10 return false; 11 12 if (bHwndIsServer == false) 13 { 14 //"Shell DocObject View"へのハンドルとして処理 15 hWnd = FindWindowEx(hWnd, NULL, _T("Internet Explorer_Server"), NULL); 16 if (hWnd == NULL) 17 return false; 18 } 19 20 nMsg = RegisterWindowMessage(_T("WM_HTML_GETOBJECT")); 21 ret = SendMessageTimeout(hWnd, nMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes); 22 if (ret == 0) 23 return false; 24 25 HRESULT hRes; 26 hRes = ObjectFromLresult(lRes, IID_IHTMLDocument2, 0, (void**)ppIHTMLDocument2); 27 28 return *ppIHTMLDocument2 ? true : false; 29}

この場合、下記2つのエラーが発生します。

LNK2019 未解決の外部シンボル ObjectFromLresult@16 が関数 "bool cdecl GetHTMLDocument2FromHWND(struct HWND *,struct IHTMLDocument2 * *,bool)" (?GetHTMLDocument2FromHWND@@YA_NPAUHWND_@@PAPAUIHTMLDocument2@@_N@Z) で参照されました

LNK1120 1 件の未解決の外部参照

未解決の外部シンボルとのことだったので、
oleacc.h で extern "C" の記載がないのかと思いましたが、
確認した所、extern "C" は記載されていました。

C++ は不慣れなもので、根本的に使い方が間違っている可能性も否めませんが、
oleacc.h のインクルードでなく、動的に oleacc.dll を利用しているのは理由があるのでしょうか。

また、oleacc.h から該当の関数を使用する場合はどの様にコーディングしたらよいのでしょうか。

疑問点その2

LPFNOBJECTFROMLRESULT についてですが、
こちらは oleacc.h で宣言されています。

何故、oleacc.h をインクルードせずに利用できるのでしょうか。

疑問点その3

参考にしたサイトのソースでは、
EnumWindows から EnumWindowsProc_ を呼び出し、
EnumWindowsProc_ から EnumWindowsProc を呼び出していました。

個人的に、EnumWindows から EnumWindowsProc を呼び出せばよいのでは?と考え、
上述のソースコードにしたのですが、
一度 EnumWindowsProc_ を経由するのには理由があるのでしょうか。

明確な理由は作った本人にしか分からないかもしれませんが、
何かしら思い当たる点がございましたらご教示下さい。

疑問点その4

参考にしたサイトのソースでは、
::IsWindow の様に、グローバル名前空間からの解決を明示していました。

上記ソースでは衝突も起こらない為、個人的に要らないかなと考えて省略しましたが、
明示した方がよいのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  • 疑問点その1

LNK2019 未解決の外部シンボル ObjectFromLresult@16 が関数 "bool cdecl GetHTMLDocument2FromHWND(struct HWND *,struct IHTMLDocument2 * *,bool)" (?GetHTMLDocument2FromHWND@@YA_NPAUHWND_@@PAPAUIHTMLDocument2@@_N@Z) で参照されました

oleacc.libをリンクしていないから。
ObjectFromLresult function
Library Oleacc.lib

  • 疑問点その2

何故、oleacc.h をインクルードせずに利用できるのでしょうか。

atlstr.hをインクルードするとその先でインクルードされているため。

  • 疑問点その3

一度 EnumWindowsProc_ を経由するのには理由があるのでしょうか。

staticではないメンバ関数を呼ぶためにはthisポインタがいるため。
リンク先の例ではクラスのメンバ変数等を使用していないのでstaticメンバ関数のみでも実現は可能ですが…

  • 疑問点その4

好みによるでしょう。

投稿2020/07/10 09:25

編集2020/07/10 09:55
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/13 05:12

ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問