📄 calcbasedddedlg.cpp
字号:
// CalcBasedDDEDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CalcBasedDDE.h"
#include "CalcBasedDDEDlg.h"
#include "dde.h"
#include "ddeml.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int DDEIndex,DDEFailRetry;
HWND DDEServerHWND,DDEClientHWND;
BOOL DDEComBusy,CalcBusy;
BOOL DDEWorkFlag;
DDE_DATA ddeReadData[DDE_READ_NUM];
DDE_DATA ddeWriteData[DDE_WRITE_NUM];
extern void InitData();
/////////////////////////////////////////////////////////////////////////////
void strcutblank(char *str)
{
char str1[256];
memcpy(str1,str,sizeof(str1));
int len=strlen(str1);
while (str1[0] == 0x20)
{
len--;
memmove(&str1[0],&str1[1],len);
}
str1[len]='\0';
strcpy(str,str1);
return;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCalcBasedDDEDlg dialog
CCalcBasedDDEDlg::CCalcBasedDDEDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCalcBasedDDEDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCalcBasedDDEDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCalcBasedDDEDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCalcBasedDDEDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCalcBasedDDEDlg, CDialog)
//{{AFX_MSG_MAP(CCalcBasedDDEDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCalcBasedDDEDlg message handlers
BOOL CCalcBasedDDEDlg::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
Sleep(2000);
mainAlive =TRUE;
DDEComBusy =TRUE;
CalcBusy =FALSE;
DDEWorkFlag =DDE_INIT;
DDEFailRetry=0;
DDEIndex=0;
InitData();
DDEClientHWND=this->GetSafeHwnd();
SetTimer(DDE_TIMER,500, NULL);
//SetTimer(WATCH_TIMER,1000,NULL);
CWinThread *m_pThread=NULL;
UINT MainCalcProcess(LPVOID lpParam);
m_pThread=AfxBeginThread(MainCalcProcess,(LPVOID)(this));
m_pThread->ResumeThread();
ShowWindow(SW_MINIMIZE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCalcBasedDDEDlg::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 CCalcBasedDDEDlg::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 CCalcBasedDDEDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCalcBasedDDEDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
ATOM atomTopic=NULL;
ATOM atomApplication=NULL;
DDEPOKE FAR *lpPokeData=NULL;
GLOBALHANDLE hPokeData=NULL;
long rslt;
char datastr[256];
HWND DDEClientHWND = this->GetSafeHwnd();
switch(nIDEvent)
{
case DDE_TIMER:
if (CalcBusy) break;
DDEComBusy=TRUE;
switch (DDEWorkFlag)
{
case DDE_INIT:
atomApplication = GlobalAddAtom(DDE_APP_NAME);
atomTopic = GlobalAddAtom(DDE_TOP_NAME);
rslt=::SendMessage((HWND)-1,WM_DDE_INITIATE,(WPARAM)DDEClientHWND,
(LPARAM)MAKELONG(atomApplication, atomTopic));
if (atomApplication != NULL)
GlobalDeleteAtom(atomApplication);
if (atomTopic != NULL)
GlobalDeleteAtom(atomTopic);
break;
case DDE_READ:
atomTopic=GlobalAddAtom(ddeReadData[DDEIndex].Tagname);
if (!(hPokeData=GlobalAlloc(GMEM_MOVEABLE,(LONG)sizeof(DDEPOKE)+lstrlen(ddeReadData[DDEIndex].Tagname)+2))) break;
if (!(lpPokeData=(DDEPOKE FAR*) GlobalLock(hPokeData)))
{
GlobalFree(hPokeData);
break;
}
rslt=::PostMessage((HWND)DDEServerHWND,WM_DDE_REQUEST,(WPARAM)DDEClientHWND,
PackDDElParam(WM_DDE_REQUEST, CF_TEXT, atomTopic));
if (!rslt)
{
DDEFailRetry++;
if (DDEFailRetry >= MAX_DDE_RETRY)
{
DDEFailRetry=0;
DDEWorkFlag=DDE_INIT;
if (atomApplication != NULL) GlobalDeleteAtom(atomApplication);
if (atomTopic != NULL) GlobalDeleteAtom(atomTopic);
if (hPokeData != NULL) GlobalFree(hPokeData);
}
}
break;
case DDE_WRITE:
atomTopic=GlobalAddAtom(ddeWriteData[DDEIndex].Tagname);
if (!(hPokeData=GlobalAlloc(GMEM_MOVEABLE,(LONG)sizeof(DDEPOKE)+lstrlen(ddeWriteData[DDEIndex].Tagname)+2))) break;
if (!(lpPokeData = (DDEPOKE FAR*) GlobalLock(hPokeData)))
{
GlobalFree(hPokeData);
break;
}
lpPokeData->fRelease = TRUE;
lpPokeData->cfFormat = CF_TEXT;
memset(datastr,0,sizeof(datastr));
sprintf(datastr,"%8.2f",ddeWriteData[DDEIndex].value);
strcutblank(datastr);
lstrcpy((LPSTR)lpPokeData->Value,(LPSTR)datastr);
lstrcat((LPSTR)lpPokeData->Value,(LPSTR)"\r\n");// Each line of CF_TEXT data is terminated by CR/LF.
GlobalUnlock(hPokeData);
rslt = ::PostMessage((HWND)DDEServerHWND,WM_DDE_POKE,(WPARAM)DDEClientHWND,
PackDDElParam(WM_DDE_POKE, (UINT)hPokeData, atomTopic));
if (!rslt)
{
DDEFailRetry++;
if (DDEFailRetry >= MAX_DDE_RETRY)
{
DDEFailRetry=0;
DDEWorkFlag=DDE_INIT;
if (atomApplication != NULL) GlobalDeleteAtom(atomApplication);
if (atomTopic != NULL) GlobalDeleteAtom(atomTopic);
if (hPokeData != NULL) GlobalFree(hPokeData);
}
}
else
{
DDEIndex++;
if (DDEIndex >= DDE_WRITE_NUM)
{
DDEIndex=0;
DDEWorkFlag=DDE_READ;
}
}
break;
default:
break;
}
case 2:
break;
default:
break;
}
CDialog::OnTimer(nIDEvent);
}
LRESULT CCalcBasedDDEDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
ATOM atomApplicationRcvd, atomTopicRcvd;
char szApplication[20], szTopic[20];
int kk;
long rslt;
DWORD cb;
UINT uiLo,i;
DDEDATA FAR *lpddedata=NULL;
GLOBALHANDLE hddedata =NULL;
BOOL brelease;
BYTE str_buf[1024];
HWND hwnd_client = this->GetSafeHwnd();
switch(message)
{
case WM_DDE_INITIATE:
atomApplicationRcvd = LOWORD(lParam);
GlobalGetAtomName(atomApplicationRcvd, szApplication, 20);
atomTopicRcvd = HIWORD(lParam);
GlobalGetAtomName(atomTopicRcvd, szTopic, 20);
break;
case WM_DDE_REQUEST:
atomApplicationRcvd = LOWORD(lParam);
GlobalGetAtomName(atomApplicationRcvd, szApplication, 20);
atomTopicRcvd = HIWORD(lParam);
GlobalGetAtomName(atomTopicRcvd, szTopic, 20);
break;
case WM_DDE_TERMINATE:
break;
case WM_QUERYOPEN:
break;
case WM_DDE_ACK:
if (DDEWorkFlag != DDE_INIT)
{
UnpackDDElParam(message, lParam, (PUINT)&uiLo, (PUINT)&atomTopicRcvd);
GlobalGetAtomName(atomTopicRcvd, szTopic, 20);
}
else
{
atomApplicationRcvd = LOWORD(lParam);
GlobalGetAtomName(atomApplicationRcvd, szApplication, 20);
atomTopicRcvd = HIWORD(lParam);
GlobalGetAtomName(atomTopicRcvd, szTopic, 20);
if (strcmpi(szApplication, DDE_APP_NAME)||strcmpi(szTopic, DDE_TOP_NAME)) break;
DDEServerHWND = (HWND)wParam;
DDEWorkFlag=DDE_READ;
KillTimer(DDE_TIMER);
SetTimer(DDE_TIMER, 100, NULL);
}
break;
case WM_DDE_DATA:
UnpackDDElParam(message, lParam, (PUINT)&hddedata, (PUINT)&atomTopicRcvd);
GlobalGetAtomName(atomTopicRcvd, szTopic, 20);
kk=-1;
for (i=0; i<DDE_READ_NUM; i++)
{
if (!strcmp(szTopic,ddeReadData[i].Tagname))
{
kk=i;
break;
}
}
lpddedata = (DDEDATA FAR*)GlobalLock(hddedata);
if ( (!lpddedata) || (lpddedata->cfFormat != CF_TEXT) )
{
rslt = ::PostMessage((HWND)DDEServerHWND,WM_DDE_ACK,(WPARAM)DDEClientHWND,
PackDDElParam(WM_DDE_ACK, 0, atomTopicRcvd));
break;
}
if (lpddedata->fAckReq)
{
rslt = ::PostMessage((HWND)DDEServerHWND,WM_DDE_ACK,(WPARAM)DDEClientHWND,
PackDDElParam(WM_DDE_ACK, 0x8000, atomTopicRcvd));
}
if ((lpddedata->cfFormat==CF_TEXT) && (kk>=0))
{
strcpy((char *)str_buf, (const char *)&lpddedata->Value[0]);
cb = strlen((const char *)str_buf);
ddeReadData[kk].value=(float)atof((char *)str_buf);
DDEIndex=kk+1;
if (DDEIndex >= DDE_READ_NUM)
{
DDEIndex=0;
DDEWorkFlag=DDE_WRITE;
DDEComBusy =FALSE;
}
}
brelease = lpddedata->fRelease;
GlobalUnlock(hddedata);
if (brelease)
GlobalFree(hddedata);
FreeDDElParam(message,lParam);
break;
default:
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
void CCalcBasedDDEDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
KillTimer(DDE_TIMER);
}
void CCalcBasedDDEDlg::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
}
void CCalcBasedDDEDlg::OnCancel()
{
// TODO: Add extra cleanup here
ShowWindow(SW_MINIMIZE);
//CDialog::OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -