ページ 11

ウインドウメッセージについて

Posted: 2013年8月11日(日) 22:23
by さこさこ
コンソールで下記のような関数を作ってウインドウメッセージを送信することができました。webサイトに乗っていました。そして、受信プログラムも探したのですがコンソールで動くプログラムがありませんでした。どのようにすれば受信できるのでしょうか。明日までの課題です。
os windows8
VC++2012Ex

コード:

void SendData()
{
COPYDATASTRUCT cd;
HWND hWnd;
char buffer[500];
 strcpy(buffer, "Hello World!");

cd.dwData = 0;
cd.cbData = strlen(buffer)+1;
cd.lpData = buffer;

hWnd = FindWindow("ReceiveApp", NULL);

SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cd);
}


Re: ウインドウメッセージについて

Posted: 2013年8月12日(月) 09:50
by さこさこ
dxライブラリを使った場合はどのように受信プログラムを書けばいいでしょうか。

Re: ウインドウメッセージについて

Posted: 2013年8月12日(月) 10:34
by へろりくしょん
状況がまるで不明なので、これだとは言えませんが。

コードから察するに、他プロセスのウィンドウとのやりとりをしたいのでしょうか。
もしそうであるならば、ちょっと面倒です。

Windows では、各プロセスの仮想メモリはそれぞれ独立してますから、ウィンドウプロシージャの差し替えなどは出来ません。
ですから、DLL等の共有空間を利用する事になります。

おそらく、システムフックを利用するのが、一般的なのでは無いでしょうか。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 05:08
by かずま
--- send.c ---

コード:

#include <windows.h>

int main()
{
    HWND hWnd = FindWindow("ReceiveApp", NULL);
    char msg[] = "hello, world";
    COPYDATASTRUCT cd;
    cd.dwData = 0;
    cd.cbData = sizeof msg;
    cd.lpData = msg;
    SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cd);
    return 0;
}
受信は、ウインドウメッセージを受けるんだから、ウインドウを作る必要があります。
--- recv.c ---

コード:

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int main()
{
    char *className = "ReceiveApp";
    HINSTANCE hInstance = GetModuleHandle(0);
    WNDCLASSEX wcex;
    HWND hWnd;

    MSG msg;
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = className;
    wcex.hIconSm        = NULL;

    if (!RegisterClassEx(&wcex)) return FALSE;
    hWnd = CreateWindow(className, "Recv Window",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        320, 240, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
    case WM_COPYDATA:
        {
            COPYDATASTRUCT *pCD = (COPYDATASTRUCT*)lParam;
            MessageBox(hWnd, (LPCSTR)pCD->lpData, "", MB_OK);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return(DefWindowProc(hWnd, msg, wParam, lParam));
    }
    return 0;
}
コンパイル
cl send.c user32.lib
cl recv.c user32.lib gdi32.lib

実行は、一つのコマンドプロンプトから、
recv
別のコマンドプロンプトから
send

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 12:52
by softya(ソフト屋)
ウィンドウ処理である必要があるのか?って事も考えないといけませんね。
あとスレッドじゃダメなのとか?
プロセス間のデータの受け渡しはTCP/IP通信やら、共有メモリ、pipeやら色々方法は有るので何をしたいかをまず明確にしてもらった方が良いと思います。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 12:55
by みけCAT
さこさこ さんが書きました:明日までの課題です。
本当にコンソールでウィンドウメッセージを受信することが課題なのでしょうか?
もし違うとしたら、元の課題の内容は何でしょうか?

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 19:34
by さこさこ
返信ありがとうございます。
dxライブラリを使ってウインドウメッセージを受信したいのですが、どうすればいのでしょうか。
かずま様の受信のプログラムをどのようにdxライブラリを使用したプログラムに組み込めばいいのか教えてください。

課題というのは自由課題です。
まだ完成していない人が多かったので来週の今日まで延期になりました。
回答お待ちしています。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 20:38
by softya(ソフト屋)
さこさこ さんが書きました:返信ありがとうございます。
dxライブラリを使ってウインドウメッセージを受信したいのですが、どうすればいのでしょうか。
かずま様の受信のプログラムをどのようにdxライブラリを使用したプログラムに組み込めばいいのか教えてください。

課題というのは自由課題です。
まだ完成していない人が多かったので来週の今日まで延期になりました。
回答お待ちしています。
なぜウィンドウメッセージであるかの説明に成っていないんですが、「なぜウィンドウメッセージ」じゃないといけないのでしょう?

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 20:47
by さこさこ
SendMessage() はウインドウメッセージのことではないのでしょうか?

とりあえずアプリケーション間で通信がしたいです。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 20:49
by softya(ソフト屋)
softya(ソフト屋) さんが書きました:ウィンドウ処理である必要があるのか?って事も考えないといけませんね。
あとスレッドじゃダメなのとか?
プロセス間のデータの受け渡しはTCP/IP通信やら、共有メモリ、pipeやら色々方法は有るので何をしたいかをまず明確にしてもらった方が良いと思います。
ウィンドウメッセージ以外も既に提案してあるんですが、スルーされているみたいなので。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 20:55
by さこさこ
スルーしてましたすいません。
スレッドの通信とかはどうすればいいのでしょうか。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 21:03
by softya(ソフト屋)
そもそも2つのプロセスに分けて何をするんでしょうか?
それが分からないとスレッド化できるかも分かりません。

DXライブラリのプログラムに対して、もう一つの通信相手のプログラムにはどんな役割が与えられているかと言うことです。
それを説明しないと2つのプログラムが動作する条件や通信するデータの量などが分かりません。と言うことは最適な回答もできません。

DXライブラリのプログラム同士でウィンドウメッセージで通信はできますが、Win32APIを勉強したいという理由がないなら、まず使わない機能です。
それよりは、スレッドを覚えたり、TCP/IPの方が使うことは多いでしょう。大量にデータを通信するなら共有メモリという選択肢もあります。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 22:07
by さこさこ
a.exeで文字を入力してエンターキーを押すとb.exeに入力した文字を表示するプログラムです。
そんなにたくさんのデータを送信するわけではないです。

自分としてはa.exeで適当な変数を定義してそのメモリにb.exeがアクセスしてその内容を表示する。
というプログラムを作ろうとしています。そのためには最初に変数のポインタをb.exeに渡してあげないとだめなのでその方法を考えています。
a.exeでファイルを作ってポインタを書き込んでb.exeで読み込むという方法を考えたのですが新たなファイルを作ったりしたくありません。
またアドレスを1度渡せばいいのでTCPとか使うのはあまり効率の良い方法ではないと思いました。そこでa.exeはコンソールアプリでb.exeはDXライブラリを使ったソフトなのでウインドウメッセージを考え付きました。というかそんな単語を聞いた覚えがあたのでその方法しか頭にありませんdした。1度しか使わないので何か良い方法はないでしょうか。

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 22:38
by softya(ソフト屋)
>そのためには最初に変数のポインタをb.exeに渡してあげないとだめなのでその方法を考えています。

a.exeのメモリにb.exeがアクセスするのは仮想記憶の仕組みからして、かなり面倒な知識を必要とします。
なので、これは避けましょう。一度しか使わないなら覚えることが多すぎます。
そう言う意味でWM_COPYDATAを使えると思っているのなら勘違いです。

WM_COPYDATAはグローバルヒープに有るポインタが得れるだけので、a.exeのメモリに直接アクセスしているわけではありません。
a.exe → グローバルヒープにコピー → b.exeがグローバルヒープから受け取る。
ここは、ちゃんと理解してください。
簡単な使い方だけ見ると、a.exeを直接覗いているようにみえるかもしれませんが。

そういう事なら、かずま さんの書いたものをDXライブラリにアレンジすればOKです。
「DXライブラリでのウインドウ最大化について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=8279#p67684
こんな事をしますが、WndProcなどWin32APIによるメッセージ処理は理解できていますか?

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 22:56
by さこさこ
私はほぼc言語の文法しか知らないといっても過言ではありません。
WndProcと言われても全くわかりません。

コンソールアプリa.exeで入力してもらった文字をdxライブラリを使って作ったアプリで受信して表示できればいいのです。
1秒間に30回送信したいです。データはそんなに多くないです。

a.exeのある変数のアドレスが0096EDD4だとするとこのアドレスをb.exeに渡してその値を読むということは簡単だと思ったのですが難しいのですね。

どうすればいいのか・・・

Re: ウインドウメッセージについて

Posted: 2013年8月13日(火) 23:10
by softya(ソフト屋)
そもそもプロセス間の通信自体がOSの仕組みのちょっと難しい部分を利用するものです。
なので、OSの仕組みをある程度を理解しないと使いこなせないシロモノなのです。
やりたい事がちょっと高レベルなので、やはり勉強してもらわないとバグでハマりそうです。

>1秒間に30回送信したいです。データはそんなに多くないです。
それなりに一秒あたりの回数が多いですね。一度には送れないんでしょうか。

どうしても通信じゃないとダメというのなら勉強してもらうって事しか無いと思います。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 07:40
by さこさこ
勉強します。
今ちょうど大学の夏休みなのでいい機会です。

何を勉強すればいのでしょうか。
私はc言語の文法程度しかわかりません。
ポインタも理解しています。
その程度です。
OSとの関係とかはわかりません。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 07:51
by さこさこ
http://128bit.blog41.fc2.com/blog-entry-32.html
でなんとなくメモリについてわかりました。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 07:55
by さこさこ
http://hw001.spaaqs.ne.jp/k-okada/compu ... d_doc.html
をみてもポインタが使えないことがわかりました

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 08:25
by さこさこ
http://www.argv.org/~chome/shmem.html
で共有メモリのプログラムが載っていたのですがc言語で書きたいのですが如何すればいいでしょうか。

共有メモリ方法は高速な通信はできるのでしょうか。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 09:17
by みけCAT
さこさこ さんが書きました:http://www.argv.org/~chome/shmem.html
で共有メモリのプログラムが載っていたのですがc言語で書きたいのですが如何すればいいでしょうか。
このサイトのコードなら、
・関数名の前についている::を全て取る
・using namespace std;を消す
・cout << なんとか << flush; → puts(なんとか); に書き換える
・cerr << なんとか << flush; → fputs(なんとか,stderr); に書き換える
・#include <iostream> → #include <stdio.h> に書き換える
・#include <ctime> → #include <time.h> に書き換える
これでコンパイルできると思います。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 09:23
by みけCAT
さこさこ さんが書きました:共有メモリ方法は高速な通信はできるのでしょうか。
Wikipediaより
Wikipedia さんが書きました:共有メモリシステムでは、全プロセッサがデータを共有しているためプログラミングが比較的容易で、同じメモリ位置へのアクセスによって高速なプロセッサ間通信が可能である。
(このWikipediaからの文はクリエイティブ・コモンズ 表示-継承 3.0 Unportedライセンスの下で利用可能です)

実際に高速と言えるかどうかは、要求される仕様にもよると思います。

Re: ウインドウメッセージについて

Posted: 2013年8月14日(水) 09:57
by softya(ソフト屋)
一方通行なら共有メモリでも構わないですが、どちらにしてもデータを更新したことを通知する手段が必要です。
そうなると、ウィンドウメッセージなどに頼ることになります。
と言うことで少データで通信するならウィンドウメッセージだけを使うのが無難ということになりますね。【誤解を招きそうなので修正】

ということで元に返ってかずまさんのコードを理解したほうが良いとなりますね。
「標準 Windows API」
http://wisdom.sakura.ne.jp/system/winap ... index.html
「Win32API(C言語)編 トップページ」
http://www.geocities.jp/ky_webid/win32c/

Re: ウインドウメッセージについて

Posted: 2013年8月15日(木) 11:02
by さこさこ
かずま様のプログラムを使用させていただくことにしました。
ありがとうございました

Re: ウインドウメッセージについて

Posted: 2013年8月15日(木) 11:11
by softya(ソフト屋)
さこさこ さんが書きました:かずま様のプログラムを使用させていただくことにしました。
ありがとうございました
DXライブラリうんぬんは良かったんですか?

Re: ウインドウメッセージについて

Posted: 2013年8月15日(木) 14:28
by さこさこ
画像の処理はそんなに重くないのでかかずま様のプログラムを使用して作成しました。