スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | スポンサー広告

WMIプログラムC++編-2補足

ブログを書いている時間がないorz

もっと気軽にブログを書くべきか(´・ω・`)



WMIプログラムC++編-2補足

えーと前回思いっきり間違っている部分がありました。

IWbemLocator::ConnectServer の6番目のパラメータの指定ですが
当然

_bstr_t(L"ntlmdomain:domain")

なわけがなく、

_bstr_t(L"ntlmdomain:任意のドメイン名")

でしたorz


後これも補足ですが
Windows2000 における COM のセキュリティの設定は

::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);

ではダメです。
(何故ダメなのかは……なぜに Windows2000 だけ?)

MSDN によると SOLE_AUTHENTICATION_LIST 構造体を使用して
セキュリティを設定してあげる必要があるようです。

// Auth Identity structure
SEC_WINNT_AUTH_IDENTITY_W auth_identity;
SOLE_AUTHENTICATION_INFO auth_info[2];
::SecureZeroMemory(&auth_identity, sizeof(auth_identity));

auth_identity.User = L"ユーザー名";
auth_identity.UserLength = wcslen(auth_identity.User);
auth_identity.Domain = L"ドメイン名";
auth_identity.DomainLength = wcslen(auth_identity.Domain);
auth_identity.Password = L"パスワード";
auth_identity.PasswordLength = wcslen(auth_identity.Password);
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

::SecureZeroMemory(auth_info, sizeof(SOLE_AUTHENTICATION_INFO)*2);

// NTLM Settings
auth_info[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
auth_info[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
auth_info[0].pAuthInfo = &auth_identity;

// Kerberos Settings
auth_info[1].dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS ;
auth_info[1].dwAuthzSvc = RPC_C_AUTHZ_NONE;
auth_info[1].pAuthInfo = &auth_identity;

SOLE_AUTHENTICATION_LIST auth_list;

auth_list.cAuthInfo = 2;
auth_list.aAuthInfo = auth_info;

::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
&auth_list, EOAC_NONE, NULL);

なお前回のプログラムは権限の設定等を特にしていないので
クライアントなどから起動して使用するには
EXEファイルをSHIFT+右クリック→「別のユーザーとして実行...」などで
ネットワークアドミニストレータ権限で実行しないと
リモートの PC にたいして接続はできますが、
プロパティの値の取得はできませんm(_ _)m

今回は以上^^;
次回はがんばって WMI for C++ にてEXEファイルを実行する方法を
紹介したいと思います。

スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.27 | Comments(0) | Trackback(0) | プログラム

WMIプログラムC++編-2

進捗状況は……特になし

そういえばGoogleの提供するブログサービス「Blogger」と「BlogSpot」が
「スプログ」のせいでえらいことになっているようだが
日本のブログサイトは大丈夫なんだろうか……何も対策とられてない予感(;´Д`)
特にここはJavaScriptが使えるだけに不安……
ブログスパムの悪夢--「スプログ」でグーグルのBloggerが大混乱-CNET



WMIプログラムC++編-2
前回約束したので今回はドメインにぶら下がっている
PCのIPAddressを取得するプログラムを解説します。

<その1>
とにもかくにもドメインにぶら下がっているPC名を取得できなければ話になりません。
そこで WNET API を使用してPC名を取得します。

<その2>
その後前回の要領で IP Address を取得するのですが
当然ネットワーク越しなのでアカウントとパスワードが必要になります。
(IWbemLocator インターフェイスの ConnectServer の
 第2パラメータにアカウント名、第3パラメータにパスワードが入ります)

<その3>
今回使用している「Win32_NetworkAdapterConfiguration」は
全てのネットワークアダプタの情報を取得できるのですが、
今回必要なのは生きているネットワークアダプタ
IP Address なので WHERE 区の後に「IPEnabled='TRUE'」と書いています。
WMI では WHERE 区の後に条件をつけることによって情報を絞ることができます。

<その4>
今回取得したい IP Address の情報は"String Array"のため少々手間が必要です。
詳細はソースを参考にしてください。

※今回は"ドメイン"、"アカウント"、"パスワード"の入力が必要のため
  GUIアプリにしました。
※何10台ものPCの検索を行うとアプリがビジー状態になるため
  スレッド化する等の工夫が必要でしょう

※2005/10/27間違ってた個所があったので修正
リソース

IDD_IP_ADDRESS DIALOG DISCARDABLE 0, 0, 183, 225
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "IP Address の列挙"
FONT 9, "MS Pゴシック"
BEGIN
LTEXT "ドメイン",IDC_STATIC,5,10,22,8
LTEXT "ユーザー",IDC_STATIC,5,35,28,8
LTEXT "パスワード",IDC_STATIC,5,60,32,8
EDITTEXT IDC_DOMAIN,40,5,70,15,ES_AUTOHSCROLL
EDITTEXT IDC_USER,40,30,70,15,ES_AUTOHSCROLL
EDITTEXT IDC_PASSWORD,40,55,70,15,ES_PASSWORD |
ES_AUTOHSCROLL
EDITTEXT IDC_LIST,5,80,175,140,ES_MULTILINE |
ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
PUSHBUTTON "取得",IDC_GET,135,5,40,15
PUSHBUTTON "閉じる",IDCANCEL,135,55,40,15
END

WinMain.cpp

#define _WIN32_DCOM
#include
#include
#include
#include "resource.h"
using namespace std;

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "Mpr.lib")

// IP Address の列挙
void IPAddressEnumerator(HWND hWnd, char *domain,
char *user, char *password)
{
IWbemLocator *wbem_locator = NULL;

// 各種初期化
::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);

::CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast(&wbem_locator));

NETRESOURCE net_resource;
LPNETRESOURCE enum_resoruce;
HANDLE enum_handle;
DWORD buffer_size = 1000;
DWORD count = 1;

::SecureZeroMemory(&net_resource, sizeof(NETRESOURCE));
net_resource.dwScope = RESOURCE_GLOBALNET;
net_resource.dwType = RESOURCETYPE_ANY;
net_resource.dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
net_resource.dwUsage = RESOURCEUSAGE_CONTAINER;
net_resource.lpRemoteName = domain;
net_resource.lpProvider = "Microsoft Windows Network";

enum_resoruce =
(LPNETRESOURCE)::GlobalAlloc(GMEM_FIXED, buffer_size);
// ネットワークリソースの取得
::WNetOpenEnum(RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
0, &net_resource, &enum_handle);

// 取得したネットワークリソースの列挙
string ip_list;
while(::WNetEnumResource(enum_handle, &count,
enum_resoruce,
&buffer_size) == NO_ERROR)
{
IWbemServices *wbem_services = NULL;
IEnumWbemClassObject *wbem_enumerator = NULL;
IWbemClassObject *wbem_object = NULL;

char pc_name[256] = "";
wsprintf(pc_name, "%s\\ROOT\\CIMV2",
enum_resoruce->lpRemoteName);
char domain_name[256] = "";
wsprintf(domain_name, "ntlmdomain:%s", domain);

// 接続開始
mbstowcs(buffer2, buffer, length);
if(wbem_locator->ConnectServer(_bstr_t(pc_name),
_bstr_t(user),
_bstr_t(password),
0, NULL, domain_name,
0, &wbem_services) != S_OK)
{
::SendDlgItemMessage(hWnd, IDC_LIST, WM_SETTEXT, 9,
reinterpret_cast("connect failed..."));
return continue;
}

::CoSetProxyBlanket(wbem_services,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE);

wbem_services->ExecQuery(_bstr_t("WQL"),
_bstr_t("SELECT * FROM
Win32_NetworkAdapterConfiguration
WHERE IPEnabled='TRUE'"),
WBEM_FLAG_RETURN_IMMEDIATELY |
WBEM_FLAG_FORWARD_ONLY,
NULL, &wbem_enumerator);

// プロパティ読み込み
ULONG returned = 0;
char cr[3] = {0x0d, 0x0a, 0x00};

while(wbem_enumerator)
{
wbem_enumerator->Next(WBEM_INFINITE, 1,
&wbem_object, &returned);

if(0 == returned) break;

VARIANT property_value;
_bstr_t display_name;
::VariantInit(&property_value);
wbem_object->Get(L"IPAddress", 0L,
&property_value, NULL, NULL);

ip_list += "IPAddress : ";
// SAFEARRAY データの取得
if(property_value.vt == (VT_ARRAY | VT_BSTR))
{
long lLower = 0, lUpper = 0;
::SAFEARRAY *property_array = property_value.parray;
::SafeArrayGetLBound(property_array, 1, &lLower);
::SafeArrayGetUBound(property_array, 1, &lUpper);

string property_string;
for(long i = lLower; i <= lUpper; ++i)
{
BSTR data;
if(::SafeArrayGetElement(property_array,
&i, &data) != S_OK)
{
if(property_array != NULL)
::SafeArrayDestroy(property_array);
}

char buffer[256] = "";
wcstombs(buffer, data, 255);
property_string += buffer;
}

if(property_array != NULL)
::SafeArrayDestroy(property_array);

ip_list += property_string;
ip_list += cr;
}

::VariantClear(&property_value);
}

// オブジェクトの開放
if(wbem_object != NULL)
wbem_object->Release();

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

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

::SendDlgItemMessage(hWnd, IDC_LIST, WM_SETTEXT,
ip_list.length(),
reinterpret_cast(ip_list.c_str()));

// 各種開放
::WNetCloseEnum(enum_handle);
::GlobalFree(enum_resoruce);
wbem_locator->Release();
}

/* ダイアログ プロシージャ */
INT_PTR CALLBACK IPDlgProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_GET:
{
char domain[256] = "";
char user[256] = "";
char password[256] = "";
::SendDlgItemMessage(hWnd, IDC_DOMAIN,
WM_GETTEXT, 255,
reinterpret_cast(domain));
::SendDlgItemMessage(hWnd, IDC_USER,
WM_GETTEXT, 255,
reinterpret_cast(user));
::SendDlgItemMessage(hWnd, IDC_PASSWORD,
WM_GETTEXT, 255,
reinterpret_cast(password));
IPAddressEnumerator(hWnd, domain, user, password);
break;
}

case IDCANCEL:
::EndDialog(hWnd, 0);
::PostQuitMessage(0);
break;
}

return 0;
}

return FALSE;
}


/* メイン */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;

::CoInitializeEx(0, COINIT_MULTITHREADED);
hWnd = ::CreateDialog(hInstance,
MAKEINTRESOURCE(IDD_IP_ADDRESS),
0, IPDlgProc);

::ShowWindow(hWnd, SW_SHOW);

while(::GetMessage(&msg, NULL, 0, 0))
{
if(hWnd == 0 || !::IsDialogMessage(hWnd, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

::CoUninitialize();
return TRUE;
}

今回は以上です。
次回はどうしようかな(;´Д`)

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.23 | Comments(0) | Trackback(0) | プログラム

WMIプログラムC++編-1

現在ゲームオーバー処理中(;´-`)y-~~

そういえばCマガをみたらなにやらSTL.NETを開発(開発終了)しているらしい……
ん~面白そうだけど.NETでプログラムするならC#選択するかな……

早くVS2005でないかなorz



WMIプログラムC++編-1

さて今回は WMI を使用してさまざまなプロパティを取得してみたいと思います。

※WMIはなんぞや? という方はこちら

WMIの利点は
・リモート上のコンピュータのさまざまな情報を取得できる
・クエリーを変更するだけでさまざまなPC上の情報を取得できる
といったところでしょうか。

ちなみに私がC++でWMIを使用することになったきっかけは
最初VBでお手軽に情報の取得をしていたのですが
どうにも遅いのが気になりました。
(特にサーバのイベントログを取得しようとした時に限界を感じました^^;)
最初WMI自体が遅いのか? とも思ったのですが
ためしにC++で組んだところ5~10倍近い速度差がでてしまい……というわけですorz

というわけで早速サンプルソースです。
これはとあるプログラム関係の掲示板に載せたものです。

このまま使用せずにラッパークラスを作った方が後々楽でしょう。
なおコンパイルするにはWMI SDKが必要です。

#define _WIN32_DCOM
#include
#include
#include
using namespace std;

#pragma comment(lib, "wbemuuid.lib")

int main(int argc, char **argv)
{
IWbemLocator *wbem_locator = NULL;
IWbemServices *wbem_services = NULL;
IEnumWbemClassObject *wbem_enumerator = NULL;

// 各種初期化
CoInitializeEx(0, COINIT_MULTITHREADED);

CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);

CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator,
reinterpret_cast(&wbem_locator));

// 接続開始
wbem_locator->ConnectServer(_bstr_t(L"\\\\.\\ROOT\\CIMV2"),
NULL, NULL, 0, NULL,
0, 0, &wbem_services);

CoSetProxyBlanket(wbem_services,
RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

wbem_services->ExecQuery(bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_ComputerSystem"),
WBEM_FLAG_RETURN_IMMEDIATELY |
WBEM_FLAG_FORWARD_ONLY ,
NULL, &wbem_enumerator);

// プロパティ読み込み
IWbemClassObject *wbem_object;
ULONG returned = 0;

while(wbem_enumerator)
{
wbem_enumerator->Next(WBEM_INFINITE, 1,
&wbem_object, &returned);

if(0 == returned)
break;

_bstr_t property_name[] = {L"Name", L"UserName", L"Domain"};

for(int item = 0; item < 3; item++)
{
VARIANT property_value;
_bstr_t display_name;
VariantInit(&property_value);
wbem_object->Get(property_name[item], 0,
&property_value, 0, 0);
display_name = property_value;
cout << static_cast(property_name[item]) <<
" : " << static_cast(display_name) << endl;
VariantClear(&property_value);
}
}

wbem_services->Release();
wbem_locator->Release();
wbem_enumerator->Release();
wbem_object->Release();

CoUninitialize();

return 0;
}


しかしこのままでは芸がありません(ぁ
なので次回はイントラネット内の同一ドメインに所属する全てのコンピュータから
IPアドレスを取得するプログラムを解説します。

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.22 | Comments(0) | Trackback(0) | プログラム

COMプログラム~

今日も特に進捗がありません(´・ω・`)
時間がorz

それにしても一見ウイルスが減ってセキュリティ意識も高くなって
インターネットが安全になってきているように見えるけど
実際にはユーザーに見えないように地下に潜っているだけなんだよな……

こういうものを見ると危機感を覚えて来る……
http://internet.watch.impress.co.jp/cda/news/2005/10/04/9350.html
http://nikkeibp.jp/sj2005/interview/22/
http://itpro.nikkeibp.co.jp/free/ITPro/NEWS/20050727/165402/



ATLを使用しないIEのイベント取得-3
※前回思いっきりクラス名を間違えていたのでひっそりと修正しておきましたorz
今回は前回作成したイベントシンククラスを使用して
IEのイベントの取得を行います。
main.cpp

#include "StdAfx.h"
#include "IEEventSink.h"

int main(int argc, char *argv[])
{
IWebBrowser2 *web_browser;

CoInitialize(NULL);
CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL,
IID_IWebBrowser2, (void **)&web_browser);

_variant_t url = "http://www.google.co.jp";

web_browser->put_Visible(VARIANT_TRUE);
web_browser->Navigate2(&url, &_variant_t(), &_variant_t(),
&_variant_t(), &_variant_t());

READYSTATE state;
// HTML ドキュメントがすべて表示されるまで待つ
while(true)
{
if(web_browser->get_ReadyState(&state) != S_OK){
printf("document read error!\n");
web_browser->Quit();
web_browser->Release();
CoUninitialize();
return -1;
}
if(state == READYSTATE_COMPLETE)
break;
}

HRESULT hr;
IConnectionPointContainer *cpc;
IConnectionPoint *cp;
IDispatch *advice_dispatch;
DWORD cookie;

// オブジェクトがイベントを発行できるかチェック
hr = web_browser->QueryInterface(IID_IConnectionPointContainer,
(void**)&cpc);

if(SUCCEEDED(hr))
{
// 接続ポイントの要求
hr = cpc->FindConnectionPoint(DIID_DWebBrowserEvents2, &cp);

if(SUCCEEDED(hr))
{
IEEventSink *ie_event;
ie_event = new IEEventSink();

ie_event->QueryInterface(IID_IDispatch,
(void **)&advice_dispatch);
// 接続~
hr = cp->Advise(advice_dispatch, &cookie);

if(SUCCEEDED(hr))
{
printf("advice success!\n");
}

cp = NULL;
}

cpc = NULL;
}

advice_dispatch->Release();
web_browser->Quit();
web_browser->Release();
CoUninitialize();

return 0;
}

StdAfx.h

#pragma once
#include <comdef.h>
#include <shlobj.h>
#include <exdispid.h>

上記を見ても分かるようにATLとほとんど変わらないと思います。

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.20 | Comments(0) | Trackback(0) | プログラム

COMプログラム~

今日は特に進捗はなし(_0_)



ATLを使用しないIEイベントの取得-2

今回はイベントシンククラスの実装を行っていきます。
といっても Invoke 以外は定型的なコードになります。

#include "stdafx.h"
#include "IEEventSink.h"

IEEventSink::IEEventSink() : m_nRefCnt(0)
{
}


IEEventSink::~IEEventSink()
{
m_nRefCnt = 0;
}


HRESULT STDMETHODCALLTYPE
IEEventSink::QueryInterface(REFIID riid, void **ppvObject)
{
if(IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IDispatch))
*ppvObject = static_cast(this);
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}

// 参照カウンタをインクリメント
AddRef();
return S_OK;
}


ULONG STDMETHODCALLTYPE IEEventSink::AddRef(void)
{
m_nRefCnt++;
return m_nRefCnt;
}


ULONG STDMETHODCALLTYPE IEEventSink::Release(void)
{
m_nRefCnt--;
if(m_nRefCnt > 0)
return m_nRefCnt;

delete this;
return 0;
}


HRESULT STDMETHODCALLTYPE
IEEventSink::GetTypeInfoCount(unsigned int *pCount)
{
if(pCount == NULL){
return E_INVALIDARG;
}

*pCount = 1;
return NOERROR;
}


HRESULT STDMETHODCALLTYPE
IEEventSink::GetTypeInfo(unsigned int iTInfo,
LCID lcid,
ITypeInfo **ppTInfo)
{
if (ppTInfo == NULL)
return E_INVALIDARG;

*ppTInfo = NULL;

if(iTInfo != 0)
return DISP_E_BADINDEX;

m_pTInfo->AddRef();

*ppTInfo = m_pTInfo;
return NOERROR;
}


HRESULT STDMETHODCALLTYPE
IEEventSink::GetIDsOfNames(REFIID riid, OLECHAR **rgszNames,
unsigned int cNames,
LCID lcid, DISPID *rgDispId)
{
return DispGetIDsOfNames(m_pTInfo, rgszNames, cNames, rgDispId);
}


HRESULT STDMETHODCALLTYPE
IEEventSink::Invoke(DISPID dispIdMember,
REFIID riid, LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
unsigned int *puArgErr)
{
switch(dispIdMember)
{
/* HTML ドキュメントの表示完了 */
case DISPID_DOCUMENTCOMPLETE:
::MessageBox(NULL, "読み込み終了", "メッセージ", MB_OK);
break;

/* ステータス変更時 */
case DISPID_STATUSTEXTCHANGE:
{
char buffer[256] = "";
wcstombs(buffer, pDispParams->rgvarg[0].bstrVal, 256);
if(strcmp(buffer , ""))
::MessageBox(NULL, buffer, "URL", MB_OK);

break;
}

/* IE のクローズ */
case DISPID_ONQUIT:
::MessageBox(NULL, "IE の終了", "メッセージ", MB_OK);
break;

default:
break;
}

return S_OK;
}


void IEEventSink::CreateInstance(IDispatch **ppDispatch)
{
IEEventSink *ie_event;
ie_event = new IEEventSink;
ie_event->QueryInterface(IID_IDispatch, (void **)ppDispatch);
}

Ivoke 以外の関数の説明は省きます。

※詳しく知りたい方はこちらを参照~
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdnguion/htm/msdn_drguion020298.asp

Ivoke についても細かい仕様は MSDN ↓
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_61id.asp

にお任せするとして……簡単に説明すると
第1引数にイベント DISPID が、
第5引数にイベントのパラメータが付随されてきます。
パラメータはイベント DISPID によって異なってくるので
各イベントシンクインターフェイスを参照してください。

IE のイベントシンクインターフェイスは↓
http://msdn.microsoft.com/workshop/browser/webbrowser/reference/ifaces/dwebbrowserevents2/dwebbrowserevents2.asp

次回に続く

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.18 | Comments(0) | Trackback(0) | プログラム

Blog開始~

どうも~
仕事やMMOで忙しくて「すとろーく」を作った後
まったくゲーム製作をしていなかったケルプです(´・ω・`)

掲示板もまったく見ておらず
続編を期待したりしている人とかがいてチョット反省しております。

というわけでゲーム製作をしつつモチベーションを上げるために
Blogを始めました。
とりあえず進捗やプログラムについて書いていこうと思います(´ω`)

内容はまだ何もいえませんが
とりあえず↓な感じです。
20051016001843.gif


※画像は仮です



ATLを使用しないIEイベントの取得-1

ATLを使用するやり方はこちらのホムペを参照
http://www.nitoyon.com/vc/tips/ie_component.htm

非ATL版もATL版とほとんど変わりません。
とりあえずイベントを受け取るためのイベントシンククラスを作る必要があります。

そのためまず IDispatch から派生させたクラスをこしらえます。

class IEEventSink : public IDispatch
{
public:
IEEventSink();
virtual ~IEEventSink();

// IUnknown
virtual HRESULT STDMETHODCALLTYPE
QueryInterface(REFIID riid, void **ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);

virtual HRESULT STDMETHODCALLTYPE
GetTypeInfoCount(unsigned int *pCount);
virtual HRESULT STDMETHODCALLTYPE
GetTypeInfo(unsigned int iTInfo,
LCID lcid, ITypeInfo **ppTInfo);
virtual HRESULT STDMETHODCALLTYPE
GetIDsOfNames(REFIID riid,
OLECHAR **rgszNames,
unsigned int cNames,
LCID lcid, DISPID *rgDispId );
// IDispatch
virtual HRESULT STDMETHODCALLTYPE
Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
unsigned int *puArgErr);

static void CreateInstance(IDispatch **ppDispatch);

public:
long m_nRefCnt;
ITypeInfo *m_pTInfo;
};

続きは次回へ~


テーマ:日記 - ジャンル:日記

2005.10.16 | Comments(0) | Trackback(0) | プログラム

«  | HOME |  »

ブロとも申請フォーム

この人とブロともになる

カウンター


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。