2014年1月7日火曜日

[MFC] 對話框以 SendMessage 傳遞 struct 結構體

接著前一篇,在兩個對話框之間傳遞資料。

同樣使用 SendMessage 來傳遞,所以直接拿上一篇的程式碼做一點修改。

同樣假設有兩個對話框 Send_Dlg 和 Receive_Dlg。

Send_Dlg: Send_Dlg.h 和 Send_Dlg.cpp

Receive_Dlg: Receive_Dlg.h 和 Receive_Dlg.cpp

Send_Dlg.h
 // 定義 訊息編號
#define WM_MYMESSAGE_USE_COSTOMIZE_MESSAGE (WM_USER + 2)

struct DataStruct
{
    int i;
    double d;
    CString m_string;
    CEdit m_edit;
};

class Send_Dlg : public CDialogEx
{
public:
    Send_Dlg(CWnd* pParent = NULL); 

    // 要傳遞的結構體
    DataStruct dataStruct;

    // 傳遞訊息的 function 
    afx_msg void sender(); 
}
Send_Dlg.cpp
#include "Send_Dlg.h"

Send_Dlg::Send_Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(Send_Dlg::IDD)
{
    m_Icon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void Send_Dlg::sender()
{
    // struct 的值
    dataStruct.i = 1;
    dataStruct.d = 1.0;
    dataStruct.m_string = L"";
    dataStruct.m_edit = "";
    // 尋找對話框名稱為 Receive_Dlg 的對話框
    CWnd* pWnd = CWnd::FindWindowW(NULL, L"Receive_Dlg");

   // 傳送訊息
    pWnd->SendMessageW(WM_MYMESSAGE_USE_COSTOMIZE_MESSAGE, (WPARAM)&dataStruct);
}

Receive_Dlg.h
#include "Send_Dlg.h"

class Receive_Dlg : public CDialogEx
{
    Receive_Dlg(CWnd* pParent = NULL);  

    // 接收訊息用的 Function
    afx_msg LRESULT receiver(WPARAM wParam, LPARAM lParam);
}

Receive_Dlg.cpp
#include "Receive_Dlg.h"

Receive_Dlg::Receive_Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(Receive_Dlg::IDD)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


 // 在 MESSAGE MAP 中加入關聯
BEGIN_MESSAGE_MAP(Receive_Dlg, CDialogEx)
    // 以 ON_MESSAGE 將 訊息ID 和 receiver 串起來
    ON_MESSAGE(WM_MYMESSAGE_USE_COSTOMIZE_MESSAGE, &Receive_Dlg::receiver) 
END_MESSAGE_MAP()

LRESULT Receive_Dlg::receiver(WPARAM wParam, LPARAM lParam)
{
    // 接受到訊息後的工作
    // do something
    
    // 接收傳過來的結構體
    DataStruct* pDs;
    pDs = (DataStruct*)wParam;

    // 取值
    pDs->i;
    pDs->d;
    pDs->m_string;
    pDs->m_edit;

    AfxMessageBox("接收到訊息");
    return LRESULT();
}


[MFC] 對話框傳訊息 SendMessage

雖然MFC已經很古老了...
不過用於簡單的程式倒是挺方便的。 
在兩個對話框中傳遞訊息的方式: SendMessage、PostMessage。

SendMessage: 在訊息傳送之後,等待接收反應才返回。
PostMessage: 在訊息傳送之後,不等待即立刻返回。


假設有兩個對話框。一個叫 Send_Dlg,一個叫 Receive_Dlg。

Send_Dlg: Send_Dlg.h 和 Send_Dlg.cpp

Receive_Dlg: Receive_Dlg.h 和 Receive_Dlg.cpp

Send_Dlg.h
 // 定義 訊息編號
#define WM_MYMESSAGE (WM_USER + 1)

class Send_Dlg : public CDialogEx
{
public:
    Send_Dlg(CWnd* pParent = NULL); 

    // 傳遞訊息的 function 
    afx_msg void sender();
}

Send_Dlg.cpp
#include "Send_Dlg.h"

Send_Dlg::Send_Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(Send_Dlg::IDD)
{
    m_Icon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void Send_Dlg::sender()
{
    // 尋找對話框名稱為 Receive_Dlg 的對話框
    CWnd* pWnd = CWnd::FindWindowW(NULL, L"Receive_Dlg");


   // 傳送訊息
    pWnd->SendMessageW(WM_MYMESSAGE);
}

Receive_Dlg.h
#include "Send_Dlg.h"

class Receive_Dlg : public CDialogEx
{
    Receive_Dlg(CWnd* pParent = NULL);  

    // 接收訊息用的 Function
    afx_msg LRESULT receiver(WPARAM wParam, LPARAM lParam);
}

Receive_Dlg.cpp
#include "Receive_Dlg.h"

Receive_Dlg::Receive_Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(Receive_Dlg::IDD)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


 // 在 MESSAGE MAP 中加入關聯
BEGIN_MESSAGE_MAP(Receive_Dlg, CDialogEx)
    // 以 ON_MESSAGE 將 訊息ID 和 receiver 串起來
    ON_MESSAGE(WM_MYMESSAGE, &Receive_Dlg::receiver) 
END_MESSAGE_MAP()

LRESULT Receive_Dlg::receiver(WPARAM wParam, LPARAM lParam)
{
    // 接受到訊息後的工作
    // do something

    AfxMessageBox("接收到訊息");
    return LRESULT();
}



參考:
MFC的SendMessage函数详解
http://blog.csdn.net/nupt123456789/article/details/7370463

MESSAGE_HANDLER [メッセージの送受信]
http://bcb.client.jp/tips/022_receive_postmessage.html


2013年12月6日金曜日

[OpenCV] SURF的使用

SIFT 和 SURF 從 2.4 版之後,被移動到 nonfree 裡面。

所以使用時必須加入下面的程式碼。

#include <opencv2/nonfree/nonfree.hpp>

#pragma comment(lib, "opencv_nonfree247d.lib")

#pragma comment(lib, "opencv_nonfree247.lib")


使用前須初始化

cv::initModule_nonfree();


2013年12月4日水曜日

2013年12月3日火曜日

[OpenCV] cv::Mat 與 IplImage 的轉換


cv::Mat → IplImage
IplImage *iplImage = cvLoadImage(imageFile, 1);

cv::Mat matImage(iplImage);


IplImage → cv::Mat
cv::Mat matImage(cv::Size(width, height), CV_8UC3);

IplImage *iplImage = cvCreateImage(cvSize(width, height), 8, 3);

iplImage = &matImage.operator IplImage();


[OpenGL] Windows 8.1 64bit 下的 OpenGL 於 Visual Studio 2012 的開發環境配置

跟 windows 7 的配置是一樣的。

這裡下載 glut-3.7.6-bin.zip。

解壓縮後將檔案如下方動作放至各資料夾中。

glut.h → C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\GL

glut.lib → C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib

glut32.dll → C:\Windows\SysWOW64


source file 中加入

#include <GL/gult.h>


應該就可以用了。

-----

另外是 freeglut的配置

這裡下載 freeglut 2.8.1 MSVC Package

配置方法同上方的OpenGL。


=====

troubleshoot

0xc000007b

The application was unable to start correctly (0xc000007b). Click OK to close the application.

檢查配置的 dll 是否正確。

32bit 的應用程式需對應 32bit 的 dll 檔,

64bit 的應用程式需對應 64bit 的 dll 檔。

但從下載來的freeglut中配置時出現錯誤的解法卻是將 32bit 的 dll 放入 64bit 的資料夾。

2013年11月19日火曜日

[OpenCV] Windows 8.1 64bit 下的 OpenCV 2.4.7 用於 Visual Studio 2012 的開發環境配置


OpenCV在2.4.4版開始支援Visual Studio 2012,下面記錄環境配置的步驟。

配置方式有很多種,這邊只用最簡單的方式。

1.  從這裡下載 Windows 版的 OpenCV。

2.  執行 OpenCV-2.4.7.exe,將解壓縮路徑指到 C:\

3.  將 C:\ 下的 opencv 變更名稱為 opencv247

4.  開發專案 x64 --> 在系統環境變數 Path 中增加 C:\opencv247\build\x64\vc11\bin;

    開發專案 win32 --> 在系統環境變數 Path 中增加 C:\opencv247\build\x86\vc11\bin;

5.  開發專案 x64 -->
     在 C:\Users\使用者名\AppData\Local\Microsoft\MSBuild\v4.0\ 資料夾下的 Microsoft.Cpp.x64.user.props 中增加下面的敘述


  <PropertyGroup>
    <IncludePath>$(IncludePath);C:\opencv247\build\include</IncludePath>
  </PropertyGroup>
  <PropertyGroup>
    <LibraryPath>$(LibraryPath);C:\opencv247\build\x64\vc11\lib</LibraryPath>
  </PropertyGroup>

    開發專案 win32 -->
     在 C:\Users\使用者名\AppData\Local\Microsoft\MSBuild\v4.0\ 資料夾下的 Microsoft.Cpp.win32.user.props 中增加下面的敘述


  <PropertyGroup>
    <IncludePath>$(IncludePath);C:\opencv247\build\include</IncludePath>
  </PropertyGroup>
  <PropertyGroup>
    <LibraryPath>$(LibraryPath);C:\opencv247\build\x86\vc11\lib</LibraryPath>
  </PropertyGroup>

加完後,看起來會像下圖一樣



















6. 在 Visual Studio 2012中新增一個C++的空專案加入下面的程式碼做測試

#include <opencv2\opencv.hpp>

#ifdef _DEBUG
#pragma comment(lib,"opencv_imgproc247d.lib")
#pragma comment(lib,"opencv_core247d.lib")
#pragma comment(lib,"opencv_highgui247d.lib")
#pragma comment(lib,"opencv_calib3d247d.lib")
#else
#pragma comment(lib,"opencv_imgproc247.lib")
#pragma comment(lib,"opencv_core247.lib")
#pragma comment(lib,"opencv_highgui247.lib")
#pragma comment(lib,"opencv_calib3d247.lib")
#endif

int main()
{
  cv::Mat img = cv::imread("圖片路徑");
  cv::imshow("test", img);
  cv::waitKey(0);
  return 0;
}


沒意外的話應該這樣就完成了(*・ω・)ノ