如下托盘程序,在主线程中计时,子线程中用Textout()显示,用Invalidate()显示为何明显抖动?
program.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by RES.rc
//
#define IDI_ICON1 102
#define IDI_ICON2 103
#define IDR_MENU1 105
#define IDB_BITMAP1 108
#define ID_EXIT 40001// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40011
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endifprogram.cpp
#include<afxwin.h>
#include"program.h"
#define WM_THREADEXIT WM_USER+103
#define WM_SHOWTHREAD WM_USER+100
#define WM_THREADQUIT WM_USER+107
BOOL threadflag=FALSE;
static HWND thexit;
NOTIFYICONDATA nid;
class mywindow: public CFrameWnd
{ public:
mywindow();
~mywindow();
BOOL PreCreateWindow(CREATESTRUCT &cs)
{
cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1));
return CFrameWnd::PreCreateWindow(cs);
}
afx_msg void OnExit()
{
PostMessage(WM_CLOSE);
}
afx_msg void OnPaint()
{ CPaintDC paintDC(this);
paintDC.TextOut(20,20,"亲爱的,你好");
}
afx_msg void OnThreadQuit()
{
PostMessage(WM_CLOSE);
}
DECLARE_MESSAGE_MAP()
};
mywindow::mywindow()
{
Create(NULL,"用户界面线程");
thexit=GetSafeHwnd();
}
mywindow::~mywindow()
{
threadflag=FALSE;
}
class UIthread: public CWinThread
{
DECLARE_DYNCREATE(UIthread)
public:
BOOL InitInstance()
{
CFrameWnd *mythread=new mywindow;
m_pMainWnd=mythread;
mythread->ShowWindow(SW_SHOW);
return TRUE;
}
};
IMPLEMENT_DYNCREATE(UIthread,CWinThread)
BEGIN_MESSAGE_MAP(mywindow,CFrameWnd)
ON_COMMAND(ID_EXIT,OnExit)
ON_WM_PAINT()
ON_MESSAGE(WM_THREADQUIT,OnThreadQuit)
END_MESSAGE_MAP()
class myframewindow: public CFrameWnd
{ public:
myframewindow();
~myframewindow();
afx_msg void OnPaint()
{ CPaintDC paintDC(this);
paintDC.TextOut(10,5,"这是主线程窗口程序");
}
afx_msg void OnWinexit()
{
PostMessage(WM_CLOSE);
}
afx_msg void OnThreadExit()
{
::PostMessage(thexit,WM_THREADQUIT,0,0);
}
void enablewin(CCmdUI *PCmd);
afx_msg LRESULT onshowthread(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
myframewindow::myframewindow()
{
Create(NULL,(LPCTSTR)"这是主线程窗口");
}
myframewindow::~myframewindow()
{
Shell_NotifyIcon(NIM_DELETE,&nid);
}
void myframewindow::enablewin(CCmdUI *PCmd)
{
PCmd->Enable(threadflag);
}LRESULT myframewindow::onshowthread(WPARAM wParam,LPARAM lParam)
{
if(wParam!=IDI_ICON1)
return 0;
switch(lParam)
{ case WM_RBUTTONUP:
{
LPPOINT lpoint=new tagPOINT;
GetCursorPos(lpoint);
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING,WM_DESTROY,"退 出");
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(MF_STRING,WM_THREADEXIT,"关闭窗口");
::SetForegroundWindow(nid.hWnd);
menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK:
{
if(!threadflag)
{ AfxBeginThread(RUNTIME_CLASS(UIthread)); threadflag=TRUE; }
}
}
return 1;
}BEGIN_MESSAGE_MAP(myframewindow,CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(WM_DESTROY,OnWinexit)
ON_COMMAND(WM_THREADEXIT,OnThreadExit)
ON_UPDATE_COMMAND_UI(WM_THREADEXIT,enablewin)
ON_MESSAGE(WM_SHOWTHREAD,onshowthread)
END_MESSAGE_MAP()class mainthd: public CWinApp
{
public:
mainthd(): CWinApp("Main Thread!"){}
BOOL InitInstance()
{
HICON hIcon=LoadIcon(IDI_ICON2);
CFrameWnd *myframe=new myframewindow;
m_pMainWnd=myframe;
nid.cbSize=sizeof(NOTIFYICONDATA);
nid.hWnd=myframe->m_hWnd;
nid.uID=IDI_ICON1;
nid.uFlags=NIF_ICON|NIF_TIP|NIF_MESSAGE;
nid.uCallbackMessage=WM_SHOWTHREAD;
nid.hIcon=LoadIcon(IDI_ICON1);
strcpy(nid.szTip,"用户界面线程及托盘演示");
Shell_NotifyIcon(NIM_ADD,&nid);
myframe->SetIcon(hIcon,FALSE);
myframe->ShowWindow(SW_HIDE);
return TRUE;
}
}mainthread;然后在设置里用FMC表态链接,我想知道如何添加program.rc文件?加入托盘图标?
program.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by RES.rc
//
#define IDI_ICON1 102
#define IDI_ICON2 103
#define IDR_MENU1 105
#define IDB_BITMAP1 108
#define ID_EXIT 40001// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40011
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endifprogram.cpp
#include<afxwin.h>
#include"program.h"
#define WM_THREADEXIT WM_USER+103
#define WM_SHOWTHREAD WM_USER+100
#define WM_THREADQUIT WM_USER+107
BOOL threadflag=FALSE;
static HWND thexit;
NOTIFYICONDATA nid;
class mywindow: public CFrameWnd
{ public:
mywindow();
~mywindow();
BOOL PreCreateWindow(CREATESTRUCT &cs)
{
cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1));
return CFrameWnd::PreCreateWindow(cs);
}
afx_msg void OnExit()
{
PostMessage(WM_CLOSE);
}
afx_msg void OnPaint()
{ CPaintDC paintDC(this);
paintDC.TextOut(20,20,"亲爱的,你好");
}
afx_msg void OnThreadQuit()
{
PostMessage(WM_CLOSE);
}
DECLARE_MESSAGE_MAP()
};
mywindow::mywindow()
{
Create(NULL,"用户界面线程");
thexit=GetSafeHwnd();
}
mywindow::~mywindow()
{
threadflag=FALSE;
}
class UIthread: public CWinThread
{
DECLARE_DYNCREATE(UIthread)
public:
BOOL InitInstance()
{
CFrameWnd *mythread=new mywindow;
m_pMainWnd=mythread;
mythread->ShowWindow(SW_SHOW);
return TRUE;
}
};
IMPLEMENT_DYNCREATE(UIthread,CWinThread)
BEGIN_MESSAGE_MAP(mywindow,CFrameWnd)
ON_COMMAND(ID_EXIT,OnExit)
ON_WM_PAINT()
ON_MESSAGE(WM_THREADQUIT,OnThreadQuit)
END_MESSAGE_MAP()
class myframewindow: public CFrameWnd
{ public:
myframewindow();
~myframewindow();
afx_msg void OnPaint()
{ CPaintDC paintDC(this);
paintDC.TextOut(10,5,"这是主线程窗口程序");
}
afx_msg void OnWinexit()
{
PostMessage(WM_CLOSE);
}
afx_msg void OnThreadExit()
{
::PostMessage(thexit,WM_THREADQUIT,0,0);
}
void enablewin(CCmdUI *PCmd);
afx_msg LRESULT onshowthread(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
myframewindow::myframewindow()
{
Create(NULL,(LPCTSTR)"这是主线程窗口");
}
myframewindow::~myframewindow()
{
Shell_NotifyIcon(NIM_DELETE,&nid);
}
void myframewindow::enablewin(CCmdUI *PCmd)
{
PCmd->Enable(threadflag);
}LRESULT myframewindow::onshowthread(WPARAM wParam,LPARAM lParam)
{
if(wParam!=IDI_ICON1)
return 0;
switch(lParam)
{ case WM_RBUTTONUP:
{
LPPOINT lpoint=new tagPOINT;
GetCursorPos(lpoint);
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING,WM_DESTROY,"退 出");
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(MF_STRING,WM_THREADEXIT,"关闭窗口");
::SetForegroundWindow(nid.hWnd);
menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK:
{
if(!threadflag)
{ AfxBeginThread(RUNTIME_CLASS(UIthread)); threadflag=TRUE; }
}
}
return 1;
}BEGIN_MESSAGE_MAP(myframewindow,CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(WM_DESTROY,OnWinexit)
ON_COMMAND(WM_THREADEXIT,OnThreadExit)
ON_UPDATE_COMMAND_UI(WM_THREADEXIT,enablewin)
ON_MESSAGE(WM_SHOWTHREAD,onshowthread)
END_MESSAGE_MAP()class mainthd: public CWinApp
{
public:
mainthd(): CWinApp("Main Thread!"){}
BOOL InitInstance()
{
HICON hIcon=LoadIcon(IDI_ICON2);
CFrameWnd *myframe=new myframewindow;
m_pMainWnd=myframe;
nid.cbSize=sizeof(NOTIFYICONDATA);
nid.hWnd=myframe->m_hWnd;
nid.uID=IDI_ICON1;
nid.uFlags=NIF_ICON|NIF_TIP|NIF_MESSAGE;
nid.uCallbackMessage=WM_SHOWTHREAD;
nid.hIcon=LoadIcon(IDI_ICON1);
strcpy(nid.szTip,"用户界面线程及托盘演示");
Shell_NotifyIcon(NIM_ADD,&nid);
myframe->SetIcon(hIcon,FALSE);
myframe->ShowWindow(SW_HIDE);
return TRUE;
}
}mainthread;然后在设置里用FMC表态链接,我想知道如何添加program.rc文件?加入托盘图标?
InvalidateRect()也不错
搜索一下,so much
InvalidateRect()用过有减轻。双缓冲没用过程序如下请帮修正:是不是线程序通信有问题?#include<afxwin.h>
#include"resource.h"
#define WM_THREADEXIT WM_USER+103
#define WM_SHOWTHREAD WM_USER+100
#define WM_THREADQUIT WM_USER+107
BOOL threadflag=FALSE;
BOOL m_bStayOnTop=TRUE;
static HWND thexit;
NOTIFYICONDATA nid;
CString m_nTime;
static int m_count=0;
CEdit m_wndEdit;
class mywindow: public CFrameWnd
{ public:
mywindow(); ~mywindow();
void SetTopMostState ()
{
CMenu* pMenu = GetSystemMenu (FALSE); if (!m_bStayOnTop) {
SetWindowPos (&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
pMenu->CheckMenuItem (IDM_SYSMENU_STAY_ON_TOP, MF_CHECKED);
}
else {
SetWindowPos (&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
pMenu->CheckMenuItem (IDM_SYSMENU_STAY_ON_TOP, MF_UNCHECKED);
}
}
BOOL PreCreateWindow(CREATESTRUCT &cs)
{
cs.hMenu=LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1));
return CFrameWnd::PreCreateWindow(cs);
}
afx_msg void OnExit()
{
PostMessage(WM_CLOSE);
}afx_msg void OnSysCommand (UINT nID, LPARAM lParam)
{
UINT nMaskedID = nID & 0xFFF0; if (nMaskedID == IDM_SYSMENU_STAY_ON_TOP) {
m_bStayOnTop = m_bStayOnTop ? 0 : 1;
SetTopMostState ();
return;
}
CWnd::OnSysCommand (nID, lParam);
}
afx_msg void OnPaint()
{
CPaintDC dc(this);
CRect rect;
CFont m_tFont;
m_tFont.CreatePointFont(280,_T ("宋体"));
CFont* pOldFont = dc.SelectObject (&m_tFont);
GetClientRect (&rect);
dc.SetViewportOrg (rect.Width () / 2, rect.Height () / 2);
dc.TextOut(-80,-20,_T(m_nTime)); Invalidate(false);
dc.SelectObject (pOldFont);
}
afx_msg int OnCreate (LPCREATESTRUCT lpcs)
{ if (CFrameWnd::OnCreate (lpcs) == -1)
return -1;
if (!SetTimer (2, 1000, NULL)) {
MessageBox (_T ("Error: SetTimer failed"));
return -1;
}
CMenu* pMenu = GetSystemMenu (FALSE);
pMenu->AppendMenu (MF_SEPARATOR);
pMenu->AppendMenu (MF_STRING, IDM_SYSMENU_STAY_ON_TOP,
_T ("Stay on To&p")); return 0; }
afx_msg void OnTimer (UINT nTimerID)
{
CTime time = CTime::GetCurrentTime ();
m_nTime.Format(_T("%0.2d:%0.2d:%0.2d"),int(m_count/3600),m_count%3600/60,m_count%60);
} afx_msg void OnThreadQuit()
{
PostMessage(WM_CLOSE); }
DECLARE_MESSAGE_MAP()
};
mywindow::mywindow()
{
CBrush brush;
brush.CreateSolidBrush(RGB(100,255,200));
CString strWndClass = AfxRegisterWndClass (
0,
AfxGetApp ()->LoadStandardCursor (IDC_ARROW),
(HBRUSH) (COLOR_WINDOW + 1),
AfxGetApp ()->LoadStandardIcon (IDI_APPLICATION) ); CreateEx (0, strWndClass, _T ("用户界面线程"),
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL);
CRect rect (0, 0, 200, 80);
CalcWindowRect (&rect); SetWindowPos (NULL, 0, 0, rect.Width (), rect.Height (),
SWP_NOMOVE );
thexit=GetSafeHwnd();}mywindow::~mywindow()
{
threadflag=FALSE;
}class UIthread: public CWinThread
{
DECLARE_DYNCREATE(UIthread)
public:
BOOL InitInstance()
{
CFrameWnd *mythread=new mywindow;
m_pMainWnd=mythread;
mythread->ShowWindow(SW_SHOW);
return TRUE;
}
};
IMPLEMENT_DYNCREATE(UIthread,CWinThread)
BEGIN_MESSAGE_MAP(mywindow,CFrameWnd)
ON_COMMAND(ID_EXIT,OnExit)
ON_WM_SYSCOMMAND()
ON_WM_CREATE ()
ON_WM_TIMER ()
ON_WM_PAINT()
ON_MESSAGE(WM_THREADQUIT,OnThreadQuit)
END_MESSAGE_MAP()class myframewindow: public CFrameWnd
{ public:
myframewindow();
~myframewindow();
afx_msg int OnCreate (LPCREATESTRUCT lpcs)
{
if (CFrameWnd::OnCreate (lpcs) == -1)
return -1; if (!SetTimer (1, 1000, NULL)) {
MessageBox (_T ("Error: SetTimer failed"));
return -1;
}
return 0;
}
afx_msg void OnTimer (UINT nTimerID)
{
CTime time = CTime::GetCurrentTime (); m_count++;
m_nTime.Format(_T("%0.2d:%0.2d:%0.2d"),int(m_count/3600),m_count%3600/60,m_count%60);}
afx_msg void OnPaint()
{
} afx_msg void OnWinexit()
{
PostMessage(WM_CLOSE);
} afx_msg void OnThreadExit()
{
::PostMessage(thexit,WM_THREADQUIT,0,0);
BOOL m_bStayOnTop=TRUE;
} void enablewin(CCmdUI *PCmd);
afx_msg LRESULT onshowthread(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
myframewindow::myframewindow()
{
Create(NULL,(LPCTSTR)"这是主线程窗口");
} myframewindow::~myframewindow()
{
Shell_NotifyIcon(NIM_DELETE,&nid);
}
void myframewindow::enablewin(CCmdUI *PCmd)
{
PCmd->Enable(threadflag);
}LRESULT myframewindow::onshowthread(WPARAM wParam,LPARAM lParam)
{
if(wParam!=IDI_ICON1)
return 0;
switch(lParam)
{ case WM_RBUTTONUP:
{
LPPOINT lpoint=new tagPOINT;
GetCursorPos(lpoint);
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING,WM_DESTROY,"退 出");
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(MF_STRING,WM_THREADEXIT,"关闭窗口");
::SetForegroundWindow(nid.hWnd);
menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDOWN:
{
if(!threadflag)
{ AfxBeginThread(RUNTIME_CLASS(UIthread)); threadflag=TRUE; }
}
}
return 1;
}BEGIN_MESSAGE_MAP(myframewindow,CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(WM_DESTROY,OnWinexit)
ON_COMMAND(WM_THREADEXIT,OnThreadExit)
ON_UPDATE_COMMAND_UI(WM_THREADEXIT,enablewin)
ON_MESSAGE(WM_SHOWTHREAD,onshowthread)
ON_WM_CREATE ()
ON_WM_TIMER ()END_MESSAGE_MAP()class mainthd: public CWinApp
{
public:
mainthd(): CWinApp("Main Thread!"){}
BOOL InitInstance()
{
HICON hIcon=LoadIcon(IDI_ICON2);
CFrameWnd *myframe=new myframewindow;
m_pMainWnd=myframe;
nid.cbSize=sizeof(NOTIFYICONDATA);
nid.hWnd=myframe->m_hWnd;
nid.uID=IDI_ICON1;
nid.uFlags=NIF_ICON|NIF_TIP|NIF_MESSAGE;
nid.uCallbackMessage=WM_SHOWTHREAD;
nid.hIcon=LoadIcon(IDI_ICON1);
strcpy(nid.szTip,"用户界面线程及托盘演示");
Shell_NotifyIcon(NIM_ADD,&nid);
myframe->SetIcon(hIcon,FALSE);
myframe->ShowWindow(SW_HIDE);
return TRUE;
}
}mainthread;
InvalidateRect()只刷新指定的rect
当然双缓冲效果更好