VC+2005 AfxBeginThread で同じクラスの異なる関数の呼び出し

[戻る]
VC+初心者@6日目 2007/02/22(木) 14:13:24
こんにちは。

タイトル表記の内容を設計している者です。
VC+初心者@6日目が設計するなよ^;と本末的なご意見あると思いますがご容赦ください。

さて、やりたい事ですが、例えばマウスクラスを実装して、
メインアプリケーションからこのマウスクラスの操作を行う際に、
1. 左クリック
2. 右クリック
3. センターホイール回転
4. マウスカーソル移動
などの関数を別々のスレッドで実行したいのです。

且つ、マウスクラスのインスタンスを構築してから、
static変数に設定値を保存しておきたいのですが、
以下の手順でVCというのは動きますでしょうか。。。

1. メインアプリ内でマウスクラスのインスタンスを構築。
2. メインアプリ内からマウスクラスのセッター経由で、マウスクラス内スタティック変
数に初期値を設定。
3. メインアプリ内からマウスクラスの操作系関数毎にスレッドを作成&実行。
4. マウスクラス内の操作系関数は、処理が終了すると関数を抜ける。
5. 終了。

初めて質問をするため意味不明かもしれませんが、
何卒よろしくお願いします。

VC+初心者@6日目 2007/02/22(木) 15:54:04
ちょっとソースを書いていました。

-MouseClass-----------------------↓
class DeviceController
{
public:
  DeviceController(void);
  static void setDeviceInfo(int dy=1280, int dx=1024, int fy=800, int fx=600);
  void cursorChange(MousePointer mp, int sleepTime);
  void leftClick();
  void rightClick();
  void centerClick();
  void centerScroll();
private:
  static int displayY;
  static int displayX;
  static int foregroundY;
  static int foregroundX;
};

void DeviceController::setDeviceInfo(int dy, int dx, int fy, int fx)
{
  DeviceController::displayY = dy;
  DeviceController::displayX = dx;
  DeviceController::foregroundY= fy;
  DeviceController::foregroundY= fx;
}
----------------------------------↑

とあって、メインスレッド側から・・・
void MainApplicationDialog::executeMouseOPE()
{
  DeviceController dc;
  dc.setDeviceInfo(dy, dx, fy, fx);
  AfxBeginThread(leftClick, dc);
  AfxBeginThread(rightClick, dc);
  AfxBeginThread(centerClick, dc);
  AfxBeginThread(centerScroll, dc);
}

という具合を想定しています。
なお、DeviceController内の操作関数ではそれぞれ可変のSleepが発生するため、
同時に動作させようとするとマルチスレッドで記述するほかないようです。

実行環境がない状態で設計をしないくてはならず、どなたかアドバイスお願いします;

シャノン 2007/02/22(木) 17:32:57
>  AfxBeginThread(leftClick, dc);
>  AfxBeginThread(rightClick, dc);
>  AfxBeginThread(centerClick, dc);
>  AfxBeginThread(centerScroll, dc);

クラスの非静的メンバはスレッド関数にできません。

やりたいことが読み取れないので何とも言えませんが、「マウスクラス」っていったい
何に使うのかなぁ…まぁそれはさておき。

AfxBeginThread の引数に渡せる関数は、
UINT __cdecl ThreadProc( LPVOID pParam );
という形でなければならず、かつ、クラスのメンバ関数の場合は静的メンバ関数でなけ
ればなりません。

ですから、たとえば

class DeviceController
{
public:
  DeviceController(void);
  static void setDeviceInfo(int dy=1280, int dx=1024, int fy=800, int fx=600);
  void StartThreads();
  void cursorChange(MousePointer mp, int sleepTime);
  static void leftClick( LPVOID pParam );
  static void rightClick( LPVOID pParam );
  static void centerClick( LPVOID pParam );
  static void centerScroll( LPVOID pParam );
  // 変数宣言は省略
};

とやっておいて、

void DeviceController::StartThreads()
{
 AfxBeginThread( &leftClick, this );
 // 以下同様にスレッド作成
}

void MainApplicationDialog::executeMouseOPE()
{
  DeviceController.setDeviceInfo(dy, dx, fy, fx);

  DeviceController dc;
  dc.StartThreads();
}

とするとか。
ただ、このコードでは、executeMouseOPEはスレッドの終了を待たずに終わってしまい、
その時点で dc がなくなってしまうので、DeviceController のインスタンスを定義する
場所を考えないといけません。

あと、排他制御も忘れずにね。

シャノン 2007/02/22(木) 17:34:20
マチガエタ。

  static UINT leftClick( LPVOID pParam );
  static UINT rightClick( LPVOID pParam );
  static UINT centerClick( LPVOID pParam );
  static UINT centerScroll( LPVOID pParam );

でないといけませんね。

#しかし…不穏な予感がしている。
#もうちょっと情報を出してもらえれば、どういう設計がいいのかアドバイスもらえる
かも

Ban 2007/02/22(木) 20:34:29
#しかし…不穏な予感がしている。

同感。

# 自動/モンキーテストツール?

VC+初心者@6日目 2007/02/23(金) 13:37:47
おはようございます。
自宅で検証してきました^;
基礎がなってなかったようで・・・。
自分の不穏な予感が。(PG担当ナムナム

上記についてですが、簡単に書かないと書きにくいと思いマウスクラスって言いました。
例えばユーザーが入力したマウスの動きをトレースするようなアプリだと考えてみてくだ
さい。
まずマウスの左ボタンを押したまま、センタースクロールを不定期でやりつつカーソル動
かす!みたいな・・・。
当然各デバイス呼び出し関数の中でSleepが多発するためシングルスレッドでは実現しな
いと思いマルチスレッドに。。。と考えた訳です。

長くなりました。
本題です。

シャノンさんのご指摘どおり、
class DeviceController
{
public:
  DeviceController(void);
  static void setDeviceInfo(int dy=1280, int dx=1024, int fy=800, int fx=600);
  static UINT cursorChange( LPVOID pParam );
  static UINT leftClick( LPVOID pParam );
  static UINT rightClick( LPVOID pParam );
  static UINT centerClick( LPVOID pParam );
  static UINT centerScroll( LPVOID pParam );
  // 変数宣言は省略
};
として、

DeviceController dc1;
DeviceController dc2;
DeviceController dc3;
DeviceController dc4;
DeviceController dc5;
void MainApplicationDialog::executeMouseOPE()
{
  DeviceController.setDeviceInfo(dy, dx, fy, fx);
  DeviceController.setXXXXXXX(mp);
   ...いろいろ
  AfxBeginThread( DeviceController::leftClick, dc1 );
}

みたくしました。
排他制御は、デバイス内でディスプレイ解像度等からの
位置計算に入れておいたところちゃんと動きました。

有り難うございました。
週末も徹夜ぎみで勉強してみます。
(どうでもいいが開発環境なしで設計させるところが一番不穏

古いスレッドには追加発言できません。