【3】QQ 聊天界面

49 篇文章 1 订阅

1.说明

稍微修改了下QQ示例里面的聊天界面界面,然后把代码扣过来完成了QQ聊天界面部分,效果还可以。

不过自己添加了消息响应:窗口抖动,截屏,字体栏的显示和隐藏


2.代码部分

// QQTalk.h文件
#ifndef __QQ_TALK_H__
#define __QQ_TALK_H__
#include <DuiLib/DuiLibEnv.h>
#include <DuiLib/UIlib.h>

using namespace DuiLib;
#define QQ_TALK_XML		_T("chatbox.xml")

class CQQTalk : public CWindowWnd, public INotifyUI
{
public:
	CQQTalk();
	~CQQTalk();
	virtual LPCTSTR	GetWindowClassName() const;		// CWindowWnd的纯虚函数,必须实现
	virtual void Notify( TNotifyUI& msg );			// INotifyUI的纯虚函数,必须实现

	// 窗口消息处理回调函数
	virtual LRESULT HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam );

private:
	// 消息处理函数
	LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);
	LRESULT OnNCActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);
	LRESULT OnNCCalcsize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);
	LRESULT OnNCPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);
	LRESULT OnDestory(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle);

	// 控件消息处理函数
	void OnNotifyClick(TNotifyUI& msg);

	// 获取窗口控件
	void	GetCtrlFromRes();
	// 窗口晃动
	void	Shake();
	// 截屏
	void	ScreenShot();

protected:
	CPaintManagerUI			m_paintManager;			// 窗口消息类管理对象

private:
	// 窗口控件列表
	CButtonUI*				m_pBtnClose;
	CButtonUI*				m_pBtnSend;
	CButtonUI*				m_pBtnCloseBox;
	CButtonUI*				m_pBtnMinBox;
	CButtonUI*				m_pBtnMaxBox;
	CButtonUI*				m_pFontBtn;
	CButtonUI*				m_pShockBtn;
	CButtonUI*				m_pScreenShotsbtn;
	CButtonUI*				m_pHomeBtn;

	CRichEditUI*			m_pInputRichEdit;
	

	CHorizontalLayoutUI*	m_pHorizonLayoutFontbar;


private:
	static LPCTSTR			m_lpszWndClsName;		// 窗口类名
	HMODULE					m_hScreenShot;			// 截屏模块句柄
};
#endif



// QQTalk.cpp文件
#include "QQTalk.h"
#include <exception>

// 截屏导出函数
typedef int (*FnStartScreenCapture)(const char* szAuth, const char* szDefaultSavePath, void* pCallBack, unsigned long hWndNotice, unsigned int noticeMsg);
typedef int (*FnInitScreenCapture)(unsigned long trackerColor, unsigned long editBorderColor, int nTransparent, int flag);

FnStartScreenCapture g_StartScreenCapture = NULL;
FnInitScreenCapture g_InitCapture = NULL;


LPCTSTR CQQTalk::m_lpszWndClsName = _T("QQTalk");

LPCTSTR CQQTalk::GetWindowClassName() const
{
	return m_lpszWndClsName;
}

void CQQTalk::Notify( TNotifyUI& msg )
{
	if(msg.sType == _T("click"))
	{
		OnNotifyClick(msg);
	}
}

LRESULT CQQTalk::HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	LRESULT lRes = 0;
	BOOL	bHandle = FALSE;

	switch(uMsg)
	{
	case WM_CREATE:		lRes = OnCreate(uMsg, wParam, lParam, bHandle);break;
	case WM_NCHITTEST:	lRes = OnNcHitTest(uMsg, wParam, lParam, bHandle);break;
	case WM_NCACTIVATE:	lRes = OnNCActivate(uMsg, wParam, lParam, bHandle);break;
	case WM_NCCALCSIZE:	lRes = OnNCCalcsize(uMsg, wParam, lParam, bHandle);break;
	case WM_NCPAINT:	lRes = OnNCPaint(uMsg, wParam, lParam, bHandle);break;
	case WM_DESTROY:	lRes = OnDestory(uMsg, wParam, lParam, bHandle);break;
	default:			lRes = FALSE;break;
	}

	if(bHandle)
	{
		return lRes;
	}
	else
	{
		if( m_paintManager.MessageHandler(uMsg, wParam, lParam, lRes) )
		{
			return lRes;
		}
		else
		{
			return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
		}
	}
}


LRESULT CQQTalk::OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	m_paintManager.Init(m_hWnd);
	CDialogBuilder builder;
	CControlUI* pRoot = builder.Create(QQ_TALK_XML, (UINT)0, NULL, &m_paintManager);
	ASSERT(pRoot && "Failed to parse XML");
	m_paintManager.AttachDialog(pRoot);
	bool bRet = m_paintManager.AddNotifier(this);
	GetCtrlFromRes();
	bHandle = TRUE;

	return 0;
}

LRESULT CQQTalk::OnNCActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	bHandle = TRUE;
	return 0;
}

LRESULT CQQTalk::OnNCCalcsize( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	bHandle = TRUE;
	return 0;
}

LRESULT CQQTalk::OnNCPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	bHandle = TRUE;
	return 0;
}
LRESULT CQQTalk::OnNcHitTest( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	bHandle = TRUE;
	POINT pt; 
	pt.x = GET_X_LPARAM(lParam); 
	pt.y = GET_Y_LPARAM(lParam);
	::ScreenToClient(*this, &pt);

	RECT rcClient;
	::GetClientRect(*this, &rcClient);


	RECT rcCaption = m_paintManager.GetCaptionRect();
	if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
		&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {
			CControlUI* pControl = static_cast<CControlUI*>(m_paintManager.FindControl(pt));
			if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 && 
				_tcscmp(pControl->GetClass(), _T("OptionUI")) != 0 &&
				_tcscmp(pControl->GetClass(), _T("TextUI")) != 0 )
				return HTCAPTION;
	}

	return HTCLIENT;
}


LRESULT CQQTalk::OnDestory( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandle )
{
	::PostQuitMessage(0L);
	bHandle = TRUE;
	return 0;
}

void CQQTalk::GetCtrlFromRes()
{
	m_pBtnClose = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("closebtn")));
	m_pBtnSend = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("sendbtn")));
	m_pBtnCloseBox = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("closebtn_box")));
	m_pBtnMinBox = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("minbtn_box")));
	m_pBtnMaxBox = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("maxbtn_box")));
	m_pFontBtn = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("fontbtn")));
	m_pShockBtn = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("shockbtn")));
	m_pScreenShotsbtn = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("screenshotsbtn")));
	m_pHomeBtn = static_cast<CButtonUI*>(m_paintManager.FindControl(_T("home")));

	m_pHorizonLayoutFontbar = static_cast<CHorizontalLayoutUI*>(m_paintManager.FindControl(_T("fontbar")));

	m_pInputRichEdit = static_cast<CRichEditUI*>(m_paintManager.FindControl(_T("input_richedit")));

	m_pBtnMaxBox->SetEnabled(false);
	m_pHorizonLayoutFontbar->SetVisible(false);
}

void CQQTalk::OnNotifyClick( TNotifyUI& msg )
{
	if( msg.pSender == m_pBtnClose || msg.pSender == m_pBtnCloseBox) 
	{
		PostQuitMessage(0);
		return;
	}

	if( msg.pSender == m_pFontBtn )
	{
		m_pHorizonLayoutFontbar->SetVisible(!m_pHorizonLayoutFontbar->IsVisible());
		return ;
	}

	if( msg.pSender == m_pShockBtn )
	{
		Shake();
		return;
	}

	if(msg.pSender == m_pScreenShotsbtn)
	{
		ScreenShot();
		return;
	}

	if ( msg.pSender == m_pHomeBtn)
	{
		ShellExecute(NULL, _T("open"), _T("http://blog.csdn.net/arbboter"), NULL,NULL, SW_MAXIMIZE);
		return;
	}

	if( msg.pSender == m_pBtnSend )
	{
		// 直接弹出消息框后果很严重
		//MessageBox(m_hWnd, _T("少年你想多了!"), _T("Message from : Arbboter"), MB_OK | MB_ICONWARNING);
		m_pInputRichEdit->SetSel(0,-1);
		m_pInputRichEdit->Clear();
		m_pInputRichEdit->AppendText(_T("想发送消息?少年你想多了!"));
		return;
	}

	if( msg.sType == _T("click"))
	{
		m_pInputRichEdit->SetSel(0,-1);
		m_pInputRichEdit->Clear();
		m_pInputRichEdit->AppendText(_T("呵呵?少年你想多了!"));
		return;
	}

}

void CQQTalk::Shake()
{

	int ty=3;
	int nFre = 30;
	CRect   m_rect;   
	GetWindowRect(this->m_hWnd, &m_rect);  
	int recordy=m_rect.left;
	int recordx=m_rect.top;

	for(int i=0;i<3;i++)
	{
		m_rect.left=recordy;
		m_rect.top=recordx;
		m_rect.top = m_rect.top + ty;  
		m_rect.left = m_rect.left - ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.top = m_rect.top -ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.top = m_rect.top -2*ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.left=m_rect.left+ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.left=m_rect.left+2*ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.top = m_rect.top + ty;  
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		Sleep(nFre);
		m_rect.top=m_rect.top+2*ty;
		SetWindowPos(this->m_hWnd, NULL,m_rect.left,m_rect.top,0,0,SWP_NOSIZE );
		SetWindowPos(this->m_hWnd, NULL,recordy,recordx,0,0,SWP_NOSIZE );
		Sleep(nFre);
	}
}

void CQQTalk::ScreenShot()
{
	g_StartScreenCapture("niuniu", "", NULL, NULL, NULL);
}

CQQTalk::CQQTalk()
{
	// 初始化截屏,借用别人的截图模块
	m_hScreenShot = LoadLibrary(_T("NiuniuCapture.dll"));
	if(m_hScreenShot)
	{
		g_StartScreenCapture = (FnStartScreenCapture)GetProcAddress(m_hScreenShot, "StartScreenCapture");
		g_InitCapture = (FnInitScreenCapture)GetProcAddress(m_hScreenShot, "InitScreenCapture");

		//设置截图边框的样式  
		g_InitCapture(RGB(255, 0, 0), RGB(0, 174, 255), 180, 0);
	}
}

CQQTalk::~CQQTalk()
{
	if(m_hScreenShot)
	{
		FreeLibrary(m_hScreenShot);
		m_hScreenShot = NULL;
	}
}



// main.cpp
// 测试文件

#include "QQTalk.h"

int WINAPI wWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPWSTR lpCmdLine, __in int nShowCmd )
{
	// 初始化CPaintManagerUI
	CPaintManagerUI::SetInstance(hInstance);
	CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin"));
	CPaintManagerUI::SetResourceZip(_T("QQRes.zip"));

	// 这一步可选
	// CoInitialize是Windows提供的API函数
	// 用来告诉 Windows以单线程的方式创建com对象
	HRESULT Hr = ::CoInitialize(NULL);
	if( FAILED(Hr) ) return 0;

	// 创建一个QQ对话界面
	CQQTalk* pQQTalkDlg = new CQQTalk();
	pQQTalkDlg->Create(NULL, _T("和XXX的对话"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
	pQQTalkDlg->CenterWindow();
	pQQTalkDlg->ShowModal();
	CPaintManagerUI::MessageLoop();
	delete pQQTalkDlg; pQQTalkDlg = NULL;

	// 逆初始化
	::CoUninitialize();
	return 0;
}


源码下载:点死我

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值