搜档网
当前位置:搜档网 › vc++6.0知识点

vc++6.0知识点


1 SetTimer函数的用法 编辑本段
UINT_PTR SetTimer(

HWND hWnd, // 窗口句柄

UINT_PTR nIDEvent, // 定时器ID,多个定时器时,可以通过该ID判断是哪个定时器

UINT uElapse, // 时间间隔,单位为毫秒

TIMERPROC lpTimerFunc // 回调函数

);

2 举例说明 编辑本段
例如

SetTimer(m_hWnd,1,1000,NULL); //一个1秒触发一次的定时器

在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了

于是SetTimer函数的原型变为:

UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,UINT ,DWORD))

当使用SetTimer函数的时候,就会生成一个计时器。函数中nIDEvent指的是计时器的标识,也就是名字。nElapse指的是时间间隔,

也就是每隔多长时间触发一次事件。第三个参数是一个回调函数,在这个函数里,放入你想要做的事情的代码,你可以将它设定为NULL,

也就是使用系统默认的回调函数,系统默认认的是onTime函数。这个函数怎么生成的呢?你需要在需要计时器的类的生成onTime函数:

在ClassWizard里,选择需要计时器的类,添加WM_TIME消息映射,就自动生成onTime函数了。然后在函数里添加代码,让代码实现功能。

每隔一段时间就会自动执行一次。

例:

SetTimer(1,1000,NULL);

1:计时器的名称;

1000:时间间隔,单位是毫秒;

NULL:使用onTime函数。

当不需要计时器的时候调用KillTimer(nIDEvent);

例如:KillTimer(1);

2) 调用回调函数

此方法首先写一个如下格式的回调函数

void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);

然后再用SetTimer(1,100,TimerProc)函数来建一个定时器,第三个参数就是回调函数地址。

二. 或许你会问,如果我要加入两个或者两个以上的 timer怎么办?

继续用SetTimer函数吧,上次的timer的ID是1,这次可以是2,3,4。。。。

SetTimer(2,1000,NULL);

SetTimer(3,500,NULL);

嗯,WINDOWS会协调他们的。当然onTimer函数体也要发生变化,要在函数体内添加每一个timer的处理代码:

onTimer(nIDEvent)

{

switch(nIDEvent)

{

case 1:........;

break;

case 2:.......;

break;

case 3:......;

break;

}

}


一、 回调函数系统自动调用
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wparam,
LPARAM lparam
);

编辑词条 WM_SYSCOMMAND

当用户从窗口菜单选择一个命令或当用户选择最大化按钮,最小化按钮,复原按钮或关闭按钮时

,一个窗口将会接收该消息
Syntax
WM_SYSCOMMAND
WPARAM wParam
LPARAM lParam;
参数
wParam
指定系统命令的类型。该参数可以是下列值之一:
SC_CLOSE
关闭窗口
SC_CONTEXTHELP
将光标改为一个问题标识样式。如果用户之后点击了对话框中的一个控件,该控件会收到一个WM_HELP消息。
SC_DEFAULT
当用户双击窗口菜单时,选择默认的条目。
SC_HOTKEY
以应用程序指定的热键激活窗口。lParam参数标识了所要激活的窗口。
SC_HSCROLL
水平滚动。
SC_KEYMENU
键盘的敲击返回窗口菜单。
SC_MAXIMIZE
最大化窗口
SC_MINIMIZE
最小化窗口
SC_MONITORPOWER
设置显示状态。该命令支持具有节电特性的设备,如电池供电的个人电脑。
lParam参数可以具有下列值:
-1 - 显示设备打开
1 - 显示设备将要进入节电模式。
2 - 显示设备将要被关闭
SC_MOUSEMENU
鼠标单击返回窗口菜单。
SC_MOVE
移动窗口
SC_NEXTWINDOW
移到下一个窗口
SC_PREVWINDOW
移到前一个窗口
SC_RESTORE
将窗口复原到原始的位置和大小。
SC_SCREENSAVE
执行System.ini文件里[boot]部分指定的屏幕保护程序。
SC_SIZE
改变窗口大小。
SC_TASKLIST
激活【开始】菜单。
SC_VSCROLL
垂直滚动。
lParam
如果一个窗口命令被鼠标选中,低位字指定光标的水平位置。否则该参数不被使用。
如果一个窗口命令被鼠标选中,高位字指定光标的垂直位置。如果使用系统加速键选择的命令,则该参数为-1,如果使用助记符的话,则该参数为0.
返回值
如果成功处理该消息,则返回值为0.
备注
获得屏幕坐标系下的位置坐标,可以使用下面的代码:
xPos = GET_X_LPARAM(lParam); // horizontal position
yPos = GET_Y_LPARAM(lParam); // vertical position 悬赏编辑词条更多

二、显示窗口
ShowWindow(SW_MAXIMIZE);
1 概述 编辑本段
函数功能:该函数设置指定窗口的显示状态。

函数原型:BOOL ShowWindow(HWND hWnd, int nCmdShow);

2 参数 编辑本段
hWnd:指窗口句柄。

nCmdShow:指定窗口如何显示。如果发送应用程序的程序提供了STARTUPINFO结构,则应用程序第一次调用ShowWindow时该参数被忽略。否则,在第一次调用ShowWindow函数时,该值应为在函数WinMain中nCmdShow参数。在随后的调用中,该参数可以为下列值之一:

SW_FORCEMINIMIZE:在WindowNT5.0中最小化窗口,即使拥有窗口的线程被挂起也会最小化。在从其他线程最小化窗口时

才使用这个参数。

SW_HIDE:隐藏窗口并激活其他窗口。

SW_MAXIMIZE:最大化指定的窗口。

SW_MINIMIZE:最小化指定的窗口并且激活在Z序中的下一个顶层窗口。

SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。

SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。

SW_SHOWDEFAULT:依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。

SW_SHOWMAXIMIZED:激活窗口并将其最大化。

SW_SHOWMINIMIZED:激活窗口并将其最小化。

SW_SHOWMINNOACTIVE:窗口最小化,激活窗口仍然维持激活状态。

SW_SHOWNA:以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。

SW_SHOWNOACTIVATE:以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。

SW_SHOWNORMAL:激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。

3 返回值 编辑本段
如果窗口之前可见,则返回值为非零。如果窗口之前被隐藏,则返回值为零。

(参考信息MSDN)

Return Values

If the window was previously visible, the return value is nonzero.

If the window was previously hidden, the return value is zero.

4 备注 编辑本段
应用程序第一次调用ShowWindow时,应该使用WinMain函数的nCmdshow参数作为它的nCmdShow参数。在随后调用ShowWindow函数时,必须使用列表中的一个给定值,而不是由WinMain函数的nCmdSHow参数指定的值。

正如在nCmdShow参数中声明的,如果调用应用程序的程序使用了在STARTUPINFO结构中指定的信息来显示窗口,则在第一次调用ShowWindow函数时nCmdShow参数就被忽略。在这种情况下,ShowWindow函数使用STARTUPINFO结构中的信息来显示窗口。在随后的调用中,应用程序必须调用ShowWindow 函数(将其中nCmdShow参数设为SW_SHOWDEFAULT)来使用由程序调用该应用程序时提供的启动信息。这个处理在下列情况下发生:

应用程序通过调用带WS_VISIBLE标志的函数来创建它们的主窗口函数;

应用程序通过调用清除了WS_VISIBLE标志的CreateWindow函数来创建主窗口函数,并且随后调用带SW_SHOW标志的ShowWindow函数来显示窗口;

Windows CE:nCmdShow参数不支持下列值:

SW_MAXIMINZE;SW_MINIMIZE;SW_RESTORE;SW_SHOWDEFAULT

SW_SHOWMAXIMIZED;SW_SHOWMINIMIZED;SW_SHOWMININOACTIVATE

速查:Windows NT

:3.1以上版本;Windows:95以上版本:Windows CE:1.0以上版本;头文件:winuw库文件:user32.lib。

5 实例 编辑本段
ShowWindow Me.lblHwnd, SW_Minimize


////////////////////////////////////////////////////////////////////////////
在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口
在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口
文章概要:GDI+的应用使得平面图形图象编程变的更加容易,本文以一个基于对话框的时钟程序为例,在VC6.0中调用*.png图片实现半透明渐变窗口,该程序实现了指针式和数字式两种时钟显示方式。窗口实现了半透明渐变窗口、窗口拖动无移动矩形框、隐藏了任务栏窗体按钮等。
一、概述
GDI+的应用使得平面图形图象编程变的更加容易,本文以一个基于对话框的时钟程序为例,在VC6.0中调用*.png图片实现半透明渐变窗口,该程序实现了指针式和数字式两种时钟显示方式。窗口实现了半透明渐变窗口、窗口拖动无移动矩形框、隐藏了任务栏窗体按钮等。
效果图如下:

图一 程序执行后与WindowXP桌面背景效果图
二、准备工作
1、图片资源准备工作。首先在Photoshop中编辑好时钟的背景、时针、分针以及数字时钟显示方式的所有图片,如下图:将这些图片保存成为带透明通道的.png格式(GDI+调用显示时能够透明调背景)。这样程序中图片资源就准备好了。
2、下面开始做好在VC6.0下展开此项工作的基本准备工作。
(1)、下载gdiplus forVC6.0的SDK,(总共两兆多)
(2)、在C盘建立文件夹“GDI+”将开发包拷贝在里面,亦即建立如下路径,以便例子代码顺利编译(当然你可以放到任意你喜欢的地方,只要在你的Project中正确包含路径即可!)。
C:\GDI+\Includes
C:\GDI+\Lib
C:\GDI+\gdiplus.dl
(3)在stdAfx.h中添加对GDI+环境的设置
1.
#define UNICODE
2.
#ifndef ULONG_PTR
3.
#define ULONG_PTR unsigned long*
4.
#endif
5.
#include "c:\gdi+\includes\gdiplus.h" ////请修改为你的头文件路径
6.
using namespace Gdiplus;
7.
#pragma comment(lib, "c:\\gdi+\\lib\\gdiplus.lib") ////请修改为你的.lib文件路径
(4)在GDIPClock.cpp中编辑app的InitInstance()中添加如下代码进行GDI+的初始化工作
1.
GdiplusStartupInput gdiplusStartupInput;
2.
ULONG_PTR gdiplusToken;
3.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
4.
......
5.
//在对话框程序结束后
6.
//关闭gdiplus的环境
7.
GdiplusShutdown(gdiplusToken);
三、程序的实现全过程
1、建立一个基于对话框的Project,这里的名称为GDIPClock
2、在GDIPClockDlg.h中定义所有类成员变量,包括所有图片的指针和图片的长宽尺寸信息。
01.
Image *m_pImageClock;
02.
Image *m_pImageClock1;
03.
Image *m_pImageHHour;
04.
Image *m_pImageHM

inu;
05.
Image *m_pImageHSec;
06.
Image *m_pImageNum;
07.
int m_BakWidth , m_BakHeight ;
08.
int m_HourWidth, m_HourHeight;
09.
int m_MinuWidth , m_MinuHeight;
10.
int m_SecWidth , m_SecHeight ;
11.
HINSTANCE hFuncInst ;
12.
Typedef BOOL (WINAPI*MYFUNC)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,
13.
COLORREF,BLENDFUNCTION*,DWORD);
14.
MYFUNC UpdateLayeredWindow;
在这一步中需要特别说明的是,在创建透明窗口式需要调用一个Windows API函数UpdateLayeredWindow(),该函数在.net以上的版本的SDK中有申明,但是在VC6.0下要调用要么下载200多兆的高版本SDK,要么从动态链接库“User32.dll”中调用,这里选择从“User32.dll”中调用。以上定义中后三项就是为此作准备的。
3、在对话框的OnCreate()中添加如下代码:对2的函数和成员变量进行初始化!(其中ImageFromIDResource()函数为从资源中载入Png图像的一个方法!)
01.
int CGDIPClockDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
02.
{
03.
if (CDialog::OnCreate(lpCreateStruct) == -1)
04.
return -1;
05.
hFuncInst = LoadLibrary("User32.DLL");
06.
BOOL bRet=FALSE;
07.
if(hFuncInst)
08.
UpdateLayeredWindow=(MYFUNC)GetProcAddress(hFuncInst, "UpdateLayeredWindow");
09.
else
10.
{
11.
AfxMessageBox("User32.dll ERROR!");
12.
exit(0);
13.
}
14.
//初始化gdiplus的环境
15.
// Initialize GDI+.
16.
m_Blend.BlendOp=0; //theonlyBlendOpdefinedinWindows2000
17.
m_Blend.BlendFlags=0; //nothingelseisspecial...
18.
m_Blend.AlphaFormat=1; //...
19.
m_Blend.SourceConstantAlpha=255;//AC_SRC_ALPHA
20.

21.
// png图片添加到资源中了在"PNG"下:所以这里可以从资源中调用,
22.
// 这里Image没有提供字节调用资源中图像的函数,
23.
// ImageFromIDResource()是通过资源名称"PNG"和资源ID号将图像
24.
// 的Image指针传递给指针应用。来完成的。
25.

26.
ImageFromIDResource(IDR_PNGBAK1,"PNG",m_pImageClock1);
27.
ImageFromIDResource(IDR_PNGNUM,"PNG",m_pImageNum);
28.
ImageFromIDResource(IDR_PNGBAK,"PNG",m_pImageClock);
29.
ImageFromIDResource(IDR_PNGHOUR,"PNG",m_pImageHHour);
30.
ImageFromIDResource(IDR_PNGMIN,"PNG",m_pImageHMinu);
31.
ImageFromIDResource(IDR_PNGSEC,"PNG",m_pImageHSec);
32.
m_BakWidth =m_pImageClock->GetWidth();
33.
m_BakHeight =m_pImageClock->GetHeight();
34.
m_HourWidth =m_pImageHHour->GetWidth();
35.
m_HourHeight=m_pImageHHour->GetHeight();
36.
m_MinuWidth =m_pImageHMinu->GetWidth();
37.
m_MinuHeight=m_pImageHMinu->GetHeight();
38.
m_SecWidth =m_pImageHSec->GetWidth();
39.
m_SecHeight =m_pImageHSec->GetHeight();
40.
::SetWindowPos(m_hWnd, HWND_TOPMOST,0,0,m_BakWidth,m_BakHeight,
41.
SWP_NOSIZE|SWP_NOMOVE);
42.
return 0;
43.
}
4.在OnInitDialog()种添加如下代码对调用透明窗体初始化和设置时钟进行刷新,代码意义有注解:
01.
//启动后立刻更新窗口样式为透明窗


02.
UpdateClockDisplay();
03.
SetTimer(1,500,NULL);
04.
//去除任务栏窗口对应按钮
05.
ModifyStyleEx (WS_EX_APPWINDOW,WS_EX_TOOLWINDOW );
06.
void CGDIPClockDlg::OnTimer(UINT nIDEvent)
07.
{
08.
// TODO: Add your message handler code here and/or call default
09.
UpdateClockDisplay();
10.
CDialog::OnTimer(nIDEvent);
11.
}
5、透明窗体创建于刷新,均调用以下函数完成,函数的参数表示整个窗体的透明度
在该函数中包括了GDI+中对Image.DrawImage()函数的集中重载方式的使用,还有在GDI+中图像变换矩阵的使用初步研究。
001.
BOOL CGDIPClockDlg::UpdateClockDisplay(int Transparent)
002.
{
003.
HDC hdcTemp=GetDC()->m_hDC;
004.
m_hdcMemory=CreateCompatibleDC(hdcTemp);
005.
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,m_BakWidth,m_BakHeight);
006.
SelectObject(m_hdcMemory,hBitMap);
007.
if(Transparent<0||Transparent>100) Transparent=100;
008.

009.
m_Blend.SourceConstantAlpha=int(Transparent*2.55);
010.
HDC hdcScreen=::GetDC (m_hWnd);
011.
RECT rct;
012.
GetWindowRect(&rct);
013.
POINT ptWinPos={rct.left,rct.top};
014.
Graphics graph(m_hdcMemory);
015.

016.
Point points[] = { Point(0, 0),
017.
Point(m_BakWidth, 0),
018.
Point(0, m_BakHeight)
019.
};
020.
static bool bFly=false;
021.
bFly?graph.DrawImage(m_pImageClock, points, 3): graph.DrawImage(m_pImageClock1, points, 3);
022.
bFly=!bFly;
023.
int OxyX=140;//m_BakWidth/2+8;
024.
int OxyY=90;//m_BakHeight/2+10;
025.
SYSTEMTIME SystemTime; // address of system time structure
026.
GetLocalTime(&SystemTime);
027.

028.
// 定义一个单位矩阵,坐标原点在表盘中央
029.
Matrix matrixH(1,0,0,1,OxyX,OxyY);
030.
// 时针旋转的角度度
031.
matrixH.Rotate(SystemTime.wHour*30+SystemTime.wMinute/2.0-180);
032.
Point pointsH[] = { Point(0, 0),Point(m_HourWidth, 0),Point(0, m_HourHeight)};
033.
matrixH.Translate(-m_HourWidth/2,-m_HourHeight/6);
034.
// 用该矩阵转换points
035.
matrixH.TransformPoints( pointsH, 3);
036.
graph.DrawImage (m_pImageHHour,pointsH, 3);
037.

038.
// 定义一个单位矩阵,坐标原点在表盘中央
039.
Matrix matrixM(1,0,0,1,OxyX,OxyY);
040.
// 分针旋转的角度度
041.
matrixM.Rotate(SystemTime.wMinute*6-180);
042.
Point pointsM[] = { Point(0, 0),Point(m_MinuWidth, 0),Point(0, m_MinuHeight)};
043.
matrixM.Translate(-m_MinuWidth/2,-m_MinuHeight/6);
044.
// 用该矩阵转换pointsM
045.
matrixM.TransformPoints( pointsM, 3);
046.
graph.DrawImage (m_pImageHMinu,pointsM, 3);
047.

048.
// 定义一个单位矩阵,坐标原点在表盘中央
049.
Matrix matrix(1,0,0,1,OxyX,OxyY);
050.
// 秒针旋转的角度度
051.
matrix.Rotate(SystemTime.wSecond*6-180);
052.
Point pointsS[] = { Point(0, 0),Point( m_SecWidth,0),Point(0,m_SecHeight )};
053.
matrix.Translate(-m_SecWidth/2,-m_SecHeight/7);
054.
// 用该矩阵转换pointsS
055.
matrix.TransformPoi

nts( pointsS, 3);
056.
graph.DrawImage (m_pImageHSec,pointsS, 3);
057.
//HH:MM:SS
058.

059.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
060.
graph.DrawImage(m_pImageNum,0, 0, 14*(SystemTime.wHour/10), 0,14,23,UnitPixel);
061.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
062.
graph.DrawImage(m_pImageNum,20,0, 14*(SystemTime.wHour%10), 0,14,23,UnitPixel);
063.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
064.
graph.DrawImage(m_pImageNum,20*2,0, 140, 0,14,23,UnitPixel);
065.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
066.
graph.DrawImage(m_pImageNum,20*3, 0, 14*(SystemTime.wMinute/10), 0,14,23,UnitPixel);
067.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
068.
graph.DrawImage(m_pImageNum,20*4,0, 14*(SystemTime.wMinute%10), 0,14,23,UnitPixel);
069.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
070.
graph.DrawImage(m_pImageNum,20*5,0, 140, 0,14,23,UnitPixel);
071.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
072.
graph.DrawImage(m_pImageNum,20*6, 0, 14*(SystemTime.wSecond/10), 0,14,23,UnitPixel);
073.
//该函数从m_pImageClock中剪切指定rect中的像素draw到指定位置
074.
graph.DrawImage(m_pImageNum,20*7,0, 14*(SystemTime.wSecond%10), 0,14,23,UnitPixel);
075.

076.
SIZE sizeWindow={m_BakWidth,m_BakHeight};
077.
POINT ptSrc={0,0};
078.
DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE);
079.
if((dwExStyle&0x80000)!=0x80000)
080.
SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);
081.

082.
BOOL bRet=FALSE;
083.
bRet= UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos,
084.
&sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2);
085.
graph.ReleaseHDC(m_hdcMemory);
086.
::ReleaseDC(m_hWnd,hdcScreen);
087.
hdcScreen=NULL;
088.
::ReleaseDC(m_hWnd,hdcTemp);
089.
hdcTemp=NULL;
090.
DeleteObject(hBitMap);
091.
DeleteDC(m_hdcMemory);
092.
m_hdcMemory=NULL;
093.
return bRet;
094.
}
095.
BOOL CGDIPClockDlg::ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
096.
{
097.
HINSTANCE hInst = AfxGetResourceHandle();
098.
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
099.
if (!hRsrc)
100.
return FALSE;
101.
// load resource into memory
102.
DWORD len = SizeofResource(hInst, hRsrc);
103.
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
104.
if (!lpRsrc)
105.
return FALSE;
106.
// Allocate global memory on which to create stream
107.
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
108.
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
109.
memcpy(pmem,lpRsrc,len);
110.
IStream* pstm;
111.
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
112.
// load from stream
113.
pImg=Gdiplus::Image::FromStream(pstm);
114.
// free/release stuff
115.
GlobalUnlock(m_hMem);
116.
pstm->Release();
117.
FreeResource(lpRsrc)

;
118.
}
119.
void CGDIPClockDlg::OnLButtonDown(UINT nFlags, CPoint point)
120.
{
121.
//禁止显示移动矩形窗体框
122.
::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,TRUE,NULL,0);
123.
//非标题栏移动整个窗口
124.
SendMessage(WM_SYSCOMMAND,0xF012,0);
125.
// PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
126.
CDialog::OnLButtonDown(nFlags, point);
127.
}

相关主题