home *** CD-ROM | disk | FTP | other *** search
- // drawdlg.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "disdraw.h"
- #include "drawdlg.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define MAX_FORMAT_NAME_LEN 256
-
- //
- // Distributed draw queue type
- //
- CLSID guidDrawType =
- { 0x151ceac0, 0xacb5, 0x11cf, { 0x8b, 0x51, 0x00, 0x20, 0xaf, 0x92, 0x95, 0x46 } };
-
- /////////////////////////////////////////////////////////////////////////////
- // CDisdrawDlg dialog
-
- CDisdrawDlg::CDisdrawDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CDisdrawDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CDisdrawDlg)
- m_strFriend = _T("");
- m_iDelivery = 0;
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
-
- void CDisdrawDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CDisdrawDlg)
- DDX_Control(pDX, IDC_DRAWAREA_SCRIBLLE, m_drawScribble);
- DDX_Control(pDX, IDC_BUTTON_ATTACH, m_btnAttach);
- DDX_Text(pDX, IDC_EDIT_FRIEND, m_strFriend);
- DDX_Radio(pDX, IDC_RADIO_EXPRESS, m_iDelivery);
- //}}AFX_DATA_MAP
- }
-
- BEGIN_MESSAGE_MAP(CDisdrawDlg, CDialog)
- //{{AFX_MSG_MAP(CDisdrawDlg)
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_BUTTON_ATTACH, OnButtonAttach)
- ON_EN_CHANGE(IDC_EDIT_FRIEND, OnChangeEditFriend)
- ON_WM_CLOSE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CDisdrawDlg message handlers
-
-
- BOOL LocateQueue(CString m_strLabel, WCHAR *wcsFormatName, DWORD dwNumChars)
- {
- //
- // Set restrictions to locate the draw queue with the specified label
- //
- DWORD cProps = 0;
- MQPROPERTYRESTRICTION aPropRestriction[2];
- MQRESTRICTION Restriction;
-
- aPropRestriction[cProps].rel = PREQ;
- aPropRestriction[cProps].prop = PROPID_Q_TYPE;
- aPropRestriction[cProps].prval.vt = VT_CLSID;
- aPropRestriction[cProps].prval.puuid = &guidDrawType;
- cProps++;
-
- WCHAR wcsLabel[MQ_MAX_Q_LABEL_LEN];
- mbstowcs(wcsLabel, m_strLabel, MQ_MAX_Q_LABEL_LEN);
- aPropRestriction[cProps].rel = PREQ;
- aPropRestriction[cProps].prop = PROPID_Q_LABEL;
- aPropRestriction[cProps].prval.vt = VT_LPWSTR;
- aPropRestriction[cProps].prval.pwszVal = wcsLabel;
- cProps++;
-
- Restriction.cRes = cProps;
- Restriction.paPropRes = aPropRestriction;
-
-
- //
- // Request the queue instance for the specified queue
- //
- cProps = 0;
- QUEUEPROPID aPropId[1];
- MQCOLUMNSET Column;
-
- aPropId[cProps] = PROPID_Q_INSTANCE;
- cProps++;
-
- Column.cCol = cProps;
- Column.aCol = aPropId;
-
-
- //
- // Locate the specified queue
- //
- HANDLE hEnum;
- BOOL fFound = FALSE;
- HRESULT hr = MQLocateBegin(NULL, &Restriction, &Column, NULL, &hEnum);
- if (!FAILED(hr))
- {
- MQPROPVARIANT aPropVar[1];
- DWORD cQueue = 1;
- hr = MQLocateNext(hEnum, &cQueue, aPropVar);
- if (!FAILED(hr) && cQueue > 0)
- {
- //
- // Obtain the format name for the located queue
- //
- hr = MQInstanceToFormatName(aPropVar[0].puuid, wcsFormatName, &dwNumChars);
- MQFreeMemory(aPropVar[0].puuid);
- if (!FAILED(hr))
- fFound = TRUE;
- }
-
- MQLocateEnd(hEnum);
- }
-
-
- return fFound;
- }
-
-
- BOOL CDisdrawDlg::OpenReceiveQueue()
- {
- //
- // Do not create the receiving queue if it already exists in the enterprise
- //
- HRESULT hr;
- WCHAR wcsFormatName[MAX_FORMAT_NAME_LEN];
- if (!LocateQueue(m_strLogin, wcsFormatName, MAX_FORMAT_NAME_LEN))
- {
- //
- // Form the pathname to the receiving queue
- //
- char mbsPathName[MQ_MAX_Q_NAME_LEN];
- DWORD dwNumChars = MQ_MAX_Q_NAME_LEN;
- GetComputerName(mbsPathName, &dwNumChars);
- strcat(mbsPathName, "\\");
- strcat(mbsPathName, m_strLogin);
-
-
- //
- // Prepare the receiving queue properties
- //
- DWORD cProps = 0;
- QUEUEPROPID aPropId[3];
- MQPROPVARIANT aPropVar[3];
- MQQUEUEPROPS propsQueue;
-
- WCHAR wcsPathName[MQ_MAX_Q_NAME_LEN];
- mbstowcs(wcsPathName, mbsPathName, MQ_MAX_Q_NAME_LEN);
- aPropId[cProps] = PROPID_Q_PATHNAME;
- aPropVar[cProps].vt = VT_LPWSTR;
- aPropVar[cProps].pwszVal = wcsPathName;
- cProps++;
-
- aPropId[cProps] = PROPID_Q_TYPE;
- aPropVar[cProps].vt = VT_CLSID;
- aPropVar[cProps].puuid = &guidDrawType;
- cProps++;
-
- WCHAR wcsLabel[MQ_MAX_Q_LABEL_LEN];
- mbstowcs(wcsLabel, m_strLogin, MQ_MAX_Q_LABEL_LEN);
- aPropId[cProps] = PROPID_Q_LABEL;
- aPropVar[cProps].vt = VT_LPWSTR;
- aPropVar[cProps].pwszVal = wcsLabel;
- cProps++;
-
- propsQueue.cProp = cProps;
- propsQueue.aPropID = aPropId;
- propsQueue.aPropVar = aPropVar;
- propsQueue.aStatus = NULL;
-
-
- //
- // Create the receiving queue
- //
- dwNumChars = MAX_FORMAT_NAME_LEN;
- hr = MQCreateQueue(NULL, &propsQueue, wcsFormatName, &dwNumChars);
-
-
- //
- // If the receiving queue already exists, obtain its format name
- //
- if (hr == MQ_ERROR_QUEUE_EXISTS)
- hr = MQPathNameToFormatName(wcsPathName, wcsFormatName, &dwNumChars);
-
- if (FAILED(hr))
- return FALSE;
- }
-
- //
- // Open the receiving queue (may need to retry due to replication latency)
- //
- while ((hr = MQOpenQueue(wcsFormatName,
- MQ_RECEIVE_ACCESS,
- 0, &m_hqIncoming)) == MQ_ERROR_QUEUE_NOT_FOUND)
- Sleep (500);
-
- if (FAILED(hr))
- return FALSE;
-
-
- return TRUE;
- }
-
-
- DWORD ReceiveUpdates(CDisdrawDlg *pDrawDlg)
- {
- //
- // Prepare the message properties to receive
- //
- DWORD cProps = 0;
- MQMSGPROPS propsMessage;
- MQPROPVARIANT aPropVar[2];
- MSGPROPID aPropId[2];
-
- WCHAR wcsBody[MAX_MSG_BODY_LEN];
- aPropId[cProps] = PROPID_M_BODY;
- aPropVar[cProps].vt = VT_UI1 | VT_VECTOR;
- aPropVar[cProps].caub.cElems = sizeof(wcsBody);
- aPropVar[cProps].caub.pElems = (UCHAR *)wcsBody;
- cProps++;
-
- aPropId[cProps] = PROPID_M_BODY_SIZE;
- aPropVar[cProps].vt = VT_UI4;
- cProps++;
-
- propsMessage.cProp = cProps;
- propsMessage.aPropID = aPropId;
- propsMessage.aPropVar = aPropVar;
- propsMessage.aStatus = NULL;
-
-
- //
- // Keep receiving updates sent to the incoming queue
- //
- HRESULT hr;
- LINE line;
- char mbsBody[MAX_MSG_BODY_LEN + 1];
-
- while (TRUE)
- {
- //
- // Synchronously receive a message from the incoming queue
- //
- hr = MQReceiveMessage(pDrawDlg->m_hqIncoming, INFINITE,
- MQ_ACTION_RECEIVE, &propsMessage,
- NULL, NULL, NULL, NULL);
-
- //
- // Determine if the message contains a keystroke or a line
- //
- if (!FAILED(hr))
- {
- //
- // Convert the body to a multi-byte null-terminated string
- //
- UINT uNumChars = aPropVar[1].ulVal/sizeof(WCHAR);
- wcstombs(mbsBody, wcsBody, uNumChars);
- mbsBody[uNumChars] = '\0';
-
- //
- // Add the keystroke to the drawing
- //
- if (uNumChars == 1)
- {
- pDrawDlg->m_drawScribble.AddKeystroke(mbsBody);
- }
-
- //
- // Add the received line to the drawing
- //
- else
- {
- sscanf(mbsBody, "%07ld%07ld%07ld%07ld",
- &line.ptStart.x, &line.ptStart.y,
- &line.ptEnd.x, &line.ptEnd.y);
- pDrawDlg->m_drawScribble.AddLine(line);
- }
- }
- }
-
-
- return 0;
- }
-
-
- BOOL CDisdrawDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
-
- // 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
-
- //
- // Display the login name in the window title
- //
- SetWindowText(m_strLogin);
-
-
- //
- // No queues are open yet
- //
- m_hqIncoming = NULL;
- m_hqOutgoing = NULL;
-
-
- //
- // Open the receiving queue and receive incoming messages
- //
- DWORD dwThreadID;
- if (OpenReceiveQueue())
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveUpdates, this, 0,
- &dwThreadID);
- else
- AfxMessageBox("Cannot open receiving queue.");
-
-
- return TRUE; // return TRUE unless you set the focus to a control
- }
-
-
- // 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 CDisdrawDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
-
- SendMessage(WM_ICONERASEBKGND, (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 to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CDisdrawDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
-
-
- void CDisdrawDlg::SendKeystroke(UINT uChar)
- {
- //
- // Send the keystroke to the friend, if any
- //
- if (m_hqOutgoing != NULL)
- {
- //
- // Prepare the message properties to send
- //
- DWORD cProps = 0;
- MQMSGPROPS propsMessage;
- MQPROPVARIANT aPropVar[5];
- MSGPROPID aPropId[5];
-
- WCHAR wcsBody[1];
- swprintf(wcsBody, L"%c", uChar);
- aPropId[cProps] = PROPID_M_BODY;
- aPropVar[cProps].vt = VT_UI1 | VT_VECTOR;
- aPropVar[cProps].caub.cElems = sizeof(wcsBody);
- aPropVar[cProps].caub.pElems = (UCHAR *)wcsBody;
- cProps++;
-
- WCHAR wcsLabel[MQ_MAX_MSG_LABEL_LEN];
- swprintf(wcsLabel, L"Key: %c", uChar);
- aPropId[cProps] = PROPID_M_LABEL;
- aPropVar[cProps].vt = VT_LPWSTR;
- aPropVar[cProps].pwszVal = wcsLabel;
- cProps++;
-
- UpdateData(TRUE);
- aPropId[cProps] = PROPID_M_DELIVERY;
- aPropVar[cProps].vt = VT_UI1;
- aPropVar[cProps].bVal = m_iDelivery;
- cProps++;
-
- aPropId[cProps] = PROPID_M_PRIORITY;
- aPropVar[cProps].vt = VT_UI1;
- aPropVar[cProps].bVal = 4;
- cProps++;
-
- aPropId[cProps] = PROPID_M_BODY_TYPE;
- aPropVar[cProps].vt = VT_UI4;
- aPropVar[cProps].lVal = (long)VT_BSTR;
- cProps++;
-
- propsMessage.cProp = cProps;
- propsMessage.aPropID = aPropId;
- propsMessage.aPropVar = aPropVar;
- propsMessage.aStatus = NULL;
-
-
- //
- // Send the message to the outgoing queue
- //
- MQSendMessage(m_hqOutgoing, &propsMessage, NULL);
- }
- }
-
-
- void CDisdrawDlg::SendMouseMovement(LINE line)
- {
- //
- // Send the line to the friend, if any
- //
- if (m_hqOutgoing != NULL)
- {
- //
- // Prepare the message properties to send
- //
- DWORD cProps = 0;
- MQMSGPROPS propsMessage;
- MQPROPVARIANT aPropVar[5];
- MSGPROPID aPropId[5];
-
- WCHAR wcsBody[MAX_MSG_BODY_LEN];
- swprintf(wcsBody, L"%07ld%07ld%07ld%07ld",
- line.ptStart.x, line.ptStart.y, line.ptEnd.x, line.ptEnd.y);
- aPropId[cProps] = PROPID_M_BODY;
- aPropVar[cProps].vt = VT_UI1 | VT_VECTOR;
- aPropVar[cProps].caub.cElems = sizeof(wcsBody);
- aPropVar[cProps].caub.pElems = (UCHAR *)wcsBody;
- cProps++;
-
- WCHAR wcsLabel[MQ_MAX_MSG_LABEL_LEN];
- swprintf(wcsLabel, L"%ld,%ld To %ld,%ld",
- line.ptStart.x, line.ptStart.y, line.ptEnd.x, line.ptEnd.y);
- aPropId[cProps] = PROPID_M_LABEL;
- aPropVar[cProps].vt = VT_LPWSTR;
- aPropVar[cProps].pwszVal = wcsLabel;
- cProps++;
-
- UpdateData(TRUE);
- aPropId[cProps] = PROPID_M_DELIVERY;
- aPropVar[cProps].vt = VT_UI1;
- aPropVar[cProps].bVal = m_iDelivery;
- cProps++;
-
- aPropId[cProps] = PROPID_M_PRIORITY;
- aPropVar[cProps].vt = VT_UI1;
- aPropVar[cProps].bVal = 3;
- cProps++;
-
- aPropId[cProps] = PROPID_M_BODY_TYPE;
- aPropVar[cProps].vt = VT_UI4;
- aPropVar[cProps].lVal = (long)VT_BSTR;
- cProps++;
-
- propsMessage.cProp = cProps;
- propsMessage.aPropID = aPropId;
- propsMessage.aPropVar = aPropVar;
- propsMessage.aStatus = NULL;
-
-
- //
- // Send the message to the outgoing queue
- //
- MQSendMessage(m_hqOutgoing, &propsMessage, NULL);
- }
- }
-
-
- void CDisdrawDlg::OnButtonAttach()
- {
- // TODO: Add your control notification handler code here
-
- //
- // Obtain the name of the friend
- //
- UpdateData(TRUE);
- m_strFriend.MakeUpper();
-
-
- //
- // Make sure the friend queue exists
- //
- WCHAR wcsFormatName[MAX_FORMAT_NAME_LEN];
- if (!LocateQueue(m_strFriend, wcsFormatName, MAX_FORMAT_NAME_LEN))
- {
- AfxMessageBox("No such friend, sorry...");
- return;
- }
-
-
- //
- // Open the friend queue for sending
- //
- HANDLE hqNewFriend;
- HRESULT hr = MQOpenQueue(wcsFormatName, MQ_SEND_ACCESS, 0, &hqNewFriend);
- if (FAILED(hr))
- AfxMessageBox("Cannot open friend queue.");
-
- else
- {
- //
- // Close the previous friend and update the window title
- //
- if (m_hqOutgoing != NULL)
- MQCloseQueue(m_hqOutgoing);
- m_hqOutgoing = hqNewFriend;
- CString strTitle = m_strLogin + " connected to " + m_strFriend;
- SetWindowText(strTitle);
- m_btnAttach.EnableWindow(FALSE);
- }
- }
-
-
- void CDisdrawDlg::OnChangeEditFriend()
- {
- // TODO: Add your control notification handler code here
-
- m_btnAttach.EnableWindow(TRUE);
- }
-
-
- void CDisdrawDlg::OnClose()
- {
- // TODO: Add your message handler code here and/or call default
-
- //
- // Close the open queues, if any
- //
- if (m_hqIncoming != NULL)
- MQCloseQueue(m_hqIncoming);
-
- if (m_hqOutgoing != NULL)
- MQCloseQueue(m_hqOutgoing);
-
- CDialog::OnClose();
- }
-