Procedure間のデータのやりとり – プログラミング – Home

Procedure間のデータのやりとり
 
通知
すべてクリア

[解決済] Procedure間のデータのやりとり


Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

OSはXP-SP2、環境はVC++6.0、SDKで行っています。よろしくお願いします。

ダイアログボックス内のエディットボックスで取得した複数の値をメインウィンドウをプ
ロシージャに送りたいのですが、グローバルで宣言した変数を使わずに送る方法はないで
しょうか?


引用未解決
トピックタグ
NowNow
 NowNow
(@NowNow)
ゲスト
結合: 20年前
投稿: 27
 

SendMessageでメインウィンドウハンドルを指定して、ユーザ定義のメッセージを送ります。
そのときに、LPARAMやWPARAMに適当な値を設定します。
適当な値とは、渡したい値そのものであったり構造体へのポインタであったり、適当に決
めます。

メインウィンドウのコールバック関数では、第二引数のUINTにあらかじめ決めたユーザ定
義メッセージが来たら、LPARAMやWPARAMを見れば、送ったデータがそのまま届きますの
で、後はご自由に。

これで、同じプロセス内であれば、自由に渡せると思います。

ただし、スタックに存在するような変数のポインタを渡し、コールバック関数内部でその
ポインタの指すメモリーを参照すると、問題が発生することもあります。


返信引用
憂
 憂
(@憂)
ゲスト
結合: 20年前
投稿: 72
 

DialogBoxParam()でポインタをダイアログ側に渡しておくという手もあるかもしれませ

あとはダイアログプロシージャの中のWM_COMMANDのIDOKなどで
そのポインタを使ってデータを格納すればいいと思います


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

NowNowさん、憂さんありがとうございます。

DialogBoxParam();の第5引数にポインタを用いてダイアログ側に渡しておくということ
でしょうか?


返信引用
憂
 憂
(@憂)
ゲスト
結合: 20年前
投稿: 72
 

例えば

struct DATA
{
受け取りたいデータ群
};

DATA data;

DialogBoxParam(略, (LPARAM)&data);

とすればダイアログのWM_INITDIALOGでその数値を受け取ることができます

それをダイアログプロシージャ内のstaticな変数に保存しておくなどすれば、
ダイアログプロシージャ内の好きな場所でポインタを使ってデータをいじれます


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

ただ、この場合は引き渡す変数がオート変数では駄目なのではないかと思います。
この方法を使う場合、引き渡す変数は少なくとも引き渡されたダイアログと同じだけの
寿命が必要だと思います。
グローバルや静的変数が嫌なのであれば、malloc等でメモリを確保して
不要になったタイミングでfreeしないといけないと思います。


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

ご返答ありがとうございます。データを構造体ではなく配列として送るにはどうしたら
よいでしょうか?

初歩的な質問ですみません、、


返信引用
KING・王
 KING・王
(@KING・王)
ゲスト
結合: 21年前
投稿: 122
 

> ご返答ありがとうございます。データを構造体ではなく配列として送るにはどうしたら
> よいでしょうか?

> DialogBoxParam(略, (LPARAM)&data);
これは、別に構造体そのものを引数で渡しているのではなく、
構造体のポインタを渡しているだけなので、
配列の場合も同じように配列の(先頭の)ポインタを渡せばOKです。

たとえばこんな感じ。

int Data[10];

DialogBoxParam(略, (LPARAM)Data);

ただし、PATIOさんも注意されていますが、変数の寿命に注意が必要です。


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

KING・王さん 初歩的な質問に返答していただきありがとうございます。

教えていただいたとおり配列でやってみたいと思います。


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

教えていただいたとおり配列でやってみたんですが、WM_INITDIALOGで受け取る時に配列
での受け取り方がうまくいかないみたいで値が入りません。

度々初歩的な質問なんですがよろしくお願いします。


返信引用
憂
 憂
(@憂)
ゲスト
結合: 20年前
投稿: 72
 

ちょっとさすがにそれだけの情報ではどこがどううまくいってないのか判断できないの
で、いくつかソースを提示したほうがいいと思います

例えば

・メインウインドウ側で宣言したデータを受け取る配列の宣言部分
・DialogBoxParamの呼び出し部分
・WM_INITDIALOGで送られてきたポインタに対して処理をしている部分
・その他ダイアログプロシージャ内でそのポインタを使用している部分

など

ポインタをどのように使用してどのように値を入れようとしたのか、
その辺をもうちょっと具体的にしましょう


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

失礼しました。

WindowProcedure内はこうなっています。
WindowProcedure()
{
switch () {
case WM_COMMAND:
switch () {
case ID:
{
int Data[4];

DialogBoxParam(略, (LPARAM)Data);
DrawLine(Data[0],Data[1],Data[2],Data[3]); <-自作の関数です
}
break;
}
break;
}
}

DialogProcedure内では、
DialogProcedure()
{
static int Data[4];

switch () {
case WM_INITDIALOG:
  : <-ここの処理が分かりません、、
:
break;
case WM_COMMAND:
switch () {
case IDOK:
{
char szString[256];

GetDlgItemText(略,szString,255);
Data[0]=atoi(szString);
同様に Data[1]=atoi(szString);
Data[2]=atoi(szString);
Data[3]=atoi(szString); // それぞれのエディットボックスから値を

取得し各配列に代入する。
EndDialog();
}
break;
}
break;
}
}
と、なっています。値1つなら受け取ることができますが配列になるとうまくいきません。
よろしくお願いします。


返信引用
憂
 憂
(@憂)
ゲスト
結合: 20年前
投稿: 72
 

> static int Data[4];

ここがいけません
WM_INITDIALOGで送られてくるのは「配列の先頭ポインタ」なので、
それを受け取るためにはint*型の変数でなくてはなりません

DialogProcedure内でこのように宣言しても、単に同じ名前というだけでまったく別物の
配列が作られるだけです
そのためそこに値を代入してもDialogProcedure内のData[]に数値が入るだけで、
WindowProcedure内のData[]にはなんの影響も及ぼしません

この場合は

static int* lpData;

というようにDialogProcedure内で宣言します
で、WM_INITDIALOGの中で

lpData = (int*)送られてきた数値;

とします
あとはそのポインタを使って数値を格納します

WM_INITDIALOGの中でどのように数値を取得するかはヘルプで調べてみてください

それとポインタの扱いに関しては非常に重要な部分なのでしっかりと扱いを覚えましょ

本が手元になければ、解説しているサイトを探しましょう
検索すればいくつかはすぐに見つかると思います

ついでにコントロールから直接数値として取得するGetDlgItemInt()という関数もあるの
で調べてみるといいかもしれません


返信引用
Y
 Y
(@Y)
ゲスト
結合: 20年前
投稿: 14
Topic starter  

憂さん、ご親切にありがとうございます。

プログラミングの勉強を始めたばかりで、まだ確実にポインタの扱いを理解できていませ
ん。なのでこれからしっかり勉強していこうと思います。ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました