DLLのスレットからイベントを発生させるとメモリエラー

解決


VB梅  2006-10-07 01:20:56  No: 63232

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を押して
メモリーエラーとなります。

動作可能な方法を教えてください。よろしくお願いします。


VB梅  2006-10-08 04:01:40  No: 63233

VB2005では動くが、VBAやVB6では動きません
いろいろ、やったけど・・・・
他のDLLから
PostThreadMessageでSetWindowsHookExにつなげてイベント発生させても
だめだった;;
素人には無理かと・・・思う


VB梅  2006-10-18 21:58:30  No: 63234

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からコントロールのハンドルを取得するのは難しいと思いあきらめました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加