VC6++のATL COM AppWizadから、イベントとスレット開始用メソッドを作成し
次のコードから、DLLを作成しました。(OSはWIN2000)
// ts.cpp : Cts のインプリメンテーション
#include "stdafx.h"
#include "Test.h"
#include "ts.h"
#include <process.h>
//////////////////////////////////////////////////////////////////////
// Cts
void Thread(LPARAM a){
while(TRUE){
((Cts*)a)->Fire_env();//イベントメソッド
Sleep(1000);
}
}
STDMETHODIMP Cts::start()
{
// TODO: この位置にインプリメント用のコードを追加してください
_beginthread((void(*)(void*))Thread ,0,this);
return S_OK;
}
このDLLをVB6で実行するとイベント発生時にメモリが"Read"にならないと言うエラーが発生します。
VB6は次の様なコードです。
Private WithEvents test As ts
Private Sub Command1_Click()
Text1.Text = 0
test.start
End Sub
Private Sub Form_Load()
Set test = New ts
End Sub
Private Sub test_env()
Text1.Text = Text1.Text + 1
End Sub
VB6上から開始するとText1が+1づつカウントされます
しかし、EXEにコンパイルして起動したプログラムではCommand1を押して
メモリーエラーとなります。
動作可能な方法を教えてください。よろしくお願いします。
VB2005では動くが、VBAやVB6では動きません
いろいろ、やったけど・・・・
他のDLLから
PostThreadMessageでSetWindowsHookExにつなげてイベント発生させても
だめだった;;
素人には無理かと・・・思う
VB6やVBAでメモリーエラーの発生について対応できました。
悩んでいる人がいましたら参考にしていただけるとうれしいです。
MFC ActiveX コントロール モジュール(OCX)が対象です
AfxBeginThread等で下のスレッドを動かします。
終了時はスレットをSuspendThread()で止めてください。
void Thread(){
OLE_HANDLE hWnd;
hWnd = COleControl::GetHwnd();//自分のコントロールハンドルを取得
while(TRUE){
::SendMessage((HWND)hWnd ,WM_TCARD,123,0);
Sleep(1000);
}
}
色々ウインドウズイベントありますが今回は WM_TCARD を利用しました。
スレットのループ内から自ハンドルにメッセージを1秒間隔で送ります。
メッセージには"123"がkeyに入ります。
このときVBに対してイベントを発生させます。
void CStcomCtrl::OnTCard(UINT key/*idAction*/, DWORD /*dwActionData*/)
{
if (key == 123)
EventSec();//親(VB)に対してイベント発生
}
ATL DLLで作ろうと試行錯誤したのですが、VB6でコントロールのハンドルがどうしても取得できなくてあきらめました。VB.Netでは取得できる。なぜ?
スレッド一覧やウインド名からの検索も考えましたが、
自DLLからコントロールのハンドルを取得するのは難しいと思いあきらめました。
ツイート | ![]() |