最近在学习怎么操作MFC的单文档操作,看了一些资料后对文档、框架、视图三者
的职能大致是这样定义的:
文档:对数据读取,写入。
框架:响应消息。
视图:显示处理结果,也包含处理数据吧我这么认为。
知道大致职能后我就开始写一个打开图片并显示的图片的小程序了。
第一步自然是建立一个单文档的工程咯。
第二步因为要打开是图片文件,所以必须得对文件过滤才行。可是在网上找到的资料
都只是针对一种类型文件的过滤。后来没办法只能自己虾头虾脑的乱搞一气,最后发现
可以这样来(发现之后才恍然大悟- -!)。
步骤一:
步骤二:
步骤三:
步骤四:
然后再这里你就可以自由发挥了。为了显示打开的图片而我是这样的做的,也是借
鉴网上提供的方法,采用定时器加上消息机制。
第一步:在CXxxView.cpp中设定好定时器。设定定时的步骤如下:
1、在定义一个resource.h中定时一个TIMER_0。
2、在CXxxView.cpp中重定义OnInitialUpdate()。
3、在OnInitialUpdate()中设置定时器SetTimer(TIMER_0, 50, NULL);
4、建立定时器响应消息,Ctrl+w将弹出一个对话框。
这时定时器的部分暂告一段落,我先定义一个消息类。代码如下:
头文件部分:
typedef struct _USERMessage
{
//-- message type --//
UINT m_Type;
//-- message content --//
WPARAM m_Context;
}USERMessage;
class CUSERMessage
{
public:
CUSERMessage();
virtual ~CUSERMessage();
//-- point to a message queue --//
USERMessage *m_MessageQueue;
//-- the size of message queue --//
INT m_MessageSize;
//-- the current size at message queue --//
INT m_MessageCurSize;
//-- the current write position --//
INT m_MessageWritePos;
//-- read position at message queue --//
INT m_MessageReadPos;
//-- set the size of message queue --//
void SetUSERMessageQueueSize(UINT size);
//-- write a message to queue --//
INT SetUSERMessageQueue(USERMessage msg);
//-- get a message fromm queue --//
INT GetUSERMessage(USERMessage *pMsg);
};
CPP文件:
CUSERMessage::CUSERMessage()
{
this->m_MessageReadPos = -1;
this->m_MessageWritePos = -1;
this->m_MessageSize = -1;
this->m_MessageCurSize = -1;
}
CUSERMessage::~CUSERMessage()
{
if (NULL != this->m_MessageQueue)
{
free(this->m_MessageQueue);
}
}
void CUSERMessage::SetUSERMessageQueueSize(UINT size)
{
if (0 == size)
{
AfxMessageBox("非法参数");
return;
}
this->m_MessageQueue = (_USERMessage*)malloc(size * sizeof(_USERMessage));
if (NULL == this->m_MessageQueue)
{
AfxMessageBox("消息队列分配失败");
return;
}
this->m_MessageReadPos = 0;
this->m_MessageWritePos = 0;
this->m_MessageCurSize = 0;
this->m_MessageSize = size;
}
INT CUSERMessage::SetUSERMessageQueue(USERMessage msg)
{
if (-1 == this->m_MessageSize)
{
return -1;
}
if (this->m_MessageSize > this->m_MessageCurSize)
{
this->m_MessageCurSize++;
memcpy(&this->m_MessageQueue[this->m_MessageWritePos++], &msg, sizeof(_USERMessage));
if (this->m_MessageSize <= this->m_MessageWritePos)
{
this->m_MessageWritePos = 0;
}
}
else
{
return -2;
}
return 0;
}
INT CUSERMessage::GetUSERMessage(USERMessage *pMsg)
{
if (-1 == this->m_MessageSize)
{
return -1;
}
if (0 < this->m_MessageCurSize)
{
this->m_MessageCurSize--;
memcpy(pMsg, &this->m_MessageQueue[this->m_MessageReadPos++], sizeof(_USERMessage));
if (this->m_MessageSize <= this->m_MessageReadPos)
{
this->m_MessageReadPos = 0;
}
}
else
{
return -2;
}
return 0;
}
这之后就是声明一个此类的全局变量咯。方便其他类使用。
这完成以后就是在CXxxView.cpp中定义个处理消息的函数。
voidCXxxView::ProcessUSERMessage()
{
USERMessage msg;
if (g_MsgQueue.GetUSERMessage(&msg))
{
return;
}
switch (msg.m_Type)
{
case WM_USER_FILE_OPEN_MSG:
{
LPCTSTR file_type = _T("图片文件(*.jpg;*.jpeg;*.gif;*.bmp;*.png)|*.jpg;*.jpeg;*.gif;*.png;*.bmp|所有文件(*.*)|*.*|");
CFileDialog file(TRUE, NULL, _T("Image file"), OFN_NOCHANGEDIR, file_type);
file.DoModal();
this->m_ImagePathName = file.GetPathName();
this->Invalidate(FALSE);
}
break;
default:
break;
}
}
注:WM_USER_FILE_OPEN_MSG是定义个消息类型
啦,到这里就很明显了,只要将此函数放入之前建立的定时器响应函数就行了。
voidCXxxView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch (nIDEvent)
{
case TIMER_0:
{
ProcessUSERMessage();
}
break;
default:
break;
}
CView::OnTimer(nIDEvent);
}
嘿嘿,到这里就差不多了,不过有些东西还得进行一些初始化啊!下面就是需要进行
初始的东西:
voidCXxxView::OnInitialUpdate()
{
SetTimer(TIMER_0, 50, NULL);
g_MsgQueue.SetUSERMessageQueueSize(3);
this->m_ImagePathName.Empty();
}
嗯,这样就完美了。这样我们就可实现通过单文档打开图片了,不过这里怎么显示图片
就另外找资料了咯。