Click here to Skip to main content
15,905,914 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Dear All,

I have two separate applications, one in MFC and other in GTK. I need to send some events (messages) to GTK (handling MFC event at GTK).

I have used CygWin to build the GTK application. Please find below the code.
I am not able to get more info on this on the net.
Please let me know how to achieve this. Examples would be more helpful as I am new to GTK.

Awaiting reply.

Thanks,
Dipak

MFC Application
C++
// MfcGtkDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MfcGtk.h"
#include "MfcGtkDlg.h"
#define WM_MINE (WM_USER+1)
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
	CAboutDlg();
// Dialog Data
	enum { IDD = IDD_ABOUTBOX };
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// CMfcGtkDlg dialog


CMfcGtkDlg::CMfcGtkDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMfcGtkDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMfcGtkDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMfcGtkDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
    ON_BN_CLICKED(IDOK, &CMfcGtkDlg::OnBnClickedOk)
    ON_BN_CLICKED(IDC_BUTTON1, &CMfcGtkDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

// CMfcGtkDlg message handlers
BOOL CMfcGtkDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	// Add "About..." menu item to system menu.
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	// TODO: Add extra initialization here
	return TRUE;  // return TRUE  unless you set the focus to a control
}
void CMfcGtkDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CMfcGtkDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}
// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMfcGtkDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMfcGtkDlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    OnOK();
}
void CMfcGtkDlg::OnBnClickedButton1()
{
    HWND hWnd = (HWND)FindWindow(NULL, _T("Hello World!")); 
    if (hWnd != NULL){    
        //GetWindowThreadProcessId(hWnd, &dwProcessId); 
        //if (dwProcessId == proc_info.dwProcessId) { 
        printf("STOP Message\n"); 
        ::PostMessage (hWnd, WM_COMMAND,0, WM_MINE); 
        //} 
    } 
    else{ 
        // printf("ERROR\n"); 
    } 
    // TODO: Add your control notification handler code here
}

GTK Application
C++
#include <gtk/gtk.h>
#include <windows.h>

#define WM_MINE (WM_USER+1)
static void destroy( GtkWidget* widget, gpointer gp)
{
	printf("dastroy called !");
        gtk_main_quit();
}
static gboolean delete_event( GtkWidget* widget, GdkEvent* event , gpointer gp)
{
	printf("delete event called !");
        return FALSE;
}

static gboolean check_msg(gpointer data)
{
	printf("Inside check_msg\n");
    int bRet;
    MSG msg;
    HWND hWnd;
    hWnd = FindWindow(NULL, "MfcGtk");
   if((NULL != hWnd)  && (-1 != (int)hWnd))
    	printf("MFC Window found\n");
    /*if(GetMessage( &msg, hWnd, 0, 0 ) != 0)
    {
		printf("Inside Message\n");
		switch(msg.message)
		{
			case WM_MINE :
				printf("START\n");
			default:
			    break;
		}
	}*/
    while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
    {
        if (bRet == -1)
        {
            printf("ERROR\n");
            // handle the error and possibly exit
        }
        else
        {
            switch(msg.message)
			{
			case WM_MINE :
				printf("START\n");
			default:
			    break;
			}
        }
    }
    return( TRUE );
}

int main(int argc, char *argv[])
{

	MSG msg;
	int bRet = 0;
	GtkWidget *window, *lavel;
    gtk_init(&argc, &argv);
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Hello World!");
    gtk_container_set_border_width( GTK_CONTAINER (window), 10);
    gtk_widget_set_size_request( window, 200, 100);
    g_signal_connect( G_OBJECT (window), "destroy", G_CALLBACK(destroy), NULL );
    g_signal_connect( G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
    ///<Add selectable level
    lavel = gtk_label_new("Hello World!");
    gtk_label_set_selectable(GTK_LABEL(lavel), TRUE);
//    gtk_label_set_markup(GTK_LABEL(lavel), "<span style='color:italic'></span>");
    ///<Add lavel as child widget of the window
    gtk_container_add( GTK_CONTAINER(window), lavel);
	gtk_widget_show_all(window);
	g_timeout_add( 200, check_msg, NULL );
	gtk_main();
	return 0;
}
Posted
Updated 11-Mar-11 0:02am
v3
Comments
strogg 11-Mar-11 4:29am    
I don't think that gtk supports win32 ipc. Looks like communicating through sockets is the better way for you.

Take a look at ACE[^]
There is an elegant solution available under "ACE_wrappers\examples\C++NPv1" - adapt it to suit your needs.

The beauty if this approach is that while relatively simple to implment, your MFC and GTK applications doesn't have to reside on the same machine, or OS - something that's often the case when you want to communicate between GTK and MFC based apps.

Best Regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 11-Mar-11 12:55pm    
ACE again? Jack of all trades...
My 5,
--SA
Espen Harlinn 11-Mar-11 13:19pm    
Thanks SAKryukov - Having an ACE on your team is usually a good thing :)
dipak2002n 14-Mar-11 2:52am    
Thanks a lot Espen for providing a solution. But i have rejected the solution as I can't use the open source. Is there any other way?
Espen Harlinn 14-Mar-11 4:00am    
There is no restriction on using ACE with commercial products, rather the opposite. GTK is both open source, and comes with a somewhat more restrictive liciense.

As an alternative - you can allways use named pipes, as they are fairly easy to set up, and still has builtin security.
Look at my article http://www.codeproject.com/KB/cross-platform/WinMsg.aspx?display=Print">Translating Windows Messaging to GTK[]

It show you how to send messages between a thread and a GTK appliction.

For your use, using two applications, you need to create a socket in both applications, then you can send data between the apps. You will need to specify the port number in both apps.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900