Help us understand the problem. What is going on with this article?

いまさらのMFC

MFCの選択

C++でWindowsの処理をするのにC++/Cliとか、C++/CXとか、C++/WinRXとかついていけないし、ハードウエア周りの処理なので、MFCでとりあえず実装することにする。
C++のDLLにして、C#でGUI実装のほうが簡単だけど、ちょっと理由があってC++ですべて作成しないといけない。
MFCのUI部と、ハードウエア周りのコードは別にして、ハードウエア周りは標準のC++で作成したいものです。
C++は最新の文法を使いたい。しかしWin32がwchar_tなので、std::stringとうまく調和しない。いろいろ変換をいれる必要がある

std::string 周りの対応

ハードウエア側はstd::stringでデータを取得するが、MFCのUIに表示するときは、whar_tに変換しないといけない。Windowsの設計思想が20年前ですからね。

MFCのCStringAとCStringを使って変換するのが簡単らしい。

std::string str = "ABCDE";
CStringA str2(str.c_str());
CString str3(str2);

エンコードがUTF-8の場合はこの方法ではうまくいかず、MultiByteToWideChar()関数で変換する必要があります。

スレッド

_biginthread などの、Windowsのローカルなスレッド関数は引数が多すぎて理解できないので、std::threadを使用したい。
ただ、メインスレッドでUIをコントロールしないといけないので、メインスレッドにメッセージを送る必要があります。
ワーカースレッド側から、postMessage関数にてWindowsのメッセージをポストし、メインスレッドのメッセージキューから独自のメッセージを処理するメソッドを設定してそちらでUIの更新をおこなうことにします。

Windowsメッセージの定義

ユーザー定義のメッセージを準備します。

SampleDialog.cpp
#define WM_SAMPLEMSG (WM_APP + 1)

それを取得するメッセージマップをMFCのマクロに追加します。
OnStart とOnStopでスレッド開始、停止をできるようにします。

SampleDialog.cpp
BEGIN_MESSAGE_MAP(SampleDialog, CDialogEx)
    ON_BN_CLICKED(IDC_BUTTON_START, &SampleDialog::OnBnClickedButtonStart)
    ON_BN_CLICKED(IDC_BUTTON_STOP, &SampleDialog::OnBnClickedButtonStop)
    ON_MESSAGE(WM_SAMPLEMSG, SampleDialog::OnMessage)
END_MESSAGE_MAP()

OnMessageメソッドをヘッダに追加

SampleDialog.h
Class SampleDilaog : public CDialogEx
{
///省略

//追加
public:
    LRESULT OnMessage(WPARAM w_param, LPARAM l_param);
    volatile bool run;
    std::thread th;

};

OnBnClickedButtonStart OnBnClickStop実装

SampleDialog.cpp
void SampleDialog::OnBnClickedButtonStart()
{
   run = true;
   th= std::thread([&]() -> void {
       while(run){
          //ハードウエアから何かデータが来る。
          if(something) {
             //ヒープに割り当てる
             std::string *ptr = new std::string("aaaa");
             PostMessageW(WM_PHOENIXMSG, 0,(LPARAM) ptr);
          }
       }

   });
}

//スレッド停止
void SampleDialog::OnBnClickedButtonStop()
{
   run = false;
}


OnMessageをソースコードに追加
ヒープの文字列データを取得して、リストビューに追加

SampleDialog.cpp
LRESULT SampleDialog::OnMessage(WPARAM w_param, LPARAM l_param)
{
    std::String * data = (Std::String*)l_param;
    CStringA dataA = CStringA(*data.c_str());
    CString dataB = CString(dataA);
    listTag.InsertItem(0,dataB );

    delete data;

    return 0;
}

コードを実行すると、スレッドからUIへデータが受け渡されます。

ynakamura-forevision
未来の理想を現実にすべく、開発を行っております。
http://www.forevision.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした