经典问题、常见问题解答收集,整理CHM版

Kudeet 2004-09-24 11:08:13
打算总结一些常见或者经典问题的答案,出一个新的CHM版。

我开这个帖子的目的是希望有时间的朋友参与进来,呵呵!一起整理啊!
可以是以前帖子的,也可以直接从FAQ、精华帖找出来整理。

我希望整理格式是:
【问题】......
【解答1】.....
【解答2】.....

10月2日结帖,希望大家积极参与整理。^_^
...全文
1409 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
angelcool 2005-01-18
  • 打赏
  • 举报
回复
mark
hzhxxx 2004-10-20
  • 打赏
  • 举报
回复
http://202.117.64.21/csdn/vcmfc.chm

不能下载了啊,其他的下载速度也很慢
wlzqi 2004-10-13
  • 打赏
  • 举报
回复
一下是得到CPU的一些信息,都是搜集来的:

// 得到CPUOEM
char * GetCPUOEM(void)
{
char OemStr[13];

_asm
{
mov eax,0
cpuid
mov DWORD PTR OemStr,ebx
mov DWORD PTR OemStr+4,edx
mov DWORD PTR OemStr+8,ecx
mov BYTE PTR OemStr+12,0
}

TCHAR szCpuOEM [MAX_PATH] ;
_stprintf ( szCpuOEM ,TEXT ( "%s" ) , OemStr) ;

return szCpuOEM ;
}

// 得到CPU速度
inline unsigned __int64 theCycleCount(void)
{
_asm _emit 0x0F
_asm _emit 0x31
//
}
class CTimer
{
unsigned __int64 m_start;
public:

unsigned __int64 m_overhead;

CTimer(void)
{
m_overhead = 0;
Start(); /// we get the start cycle
m_overhead = Stop();
// then we get the stop cycle catching the overhead time
}

void Start(void)
{
m_start = theCycleCount();
}
unsigned __int64 Stop(void)
{
/// with the stop cycle we remove the overhead's time
return theCycleCount()-m_start-m_overhead;}
};

然后使用这个函数
double GetCPUSpeed(void)
{

TCHAR szRawClockFreq [MAX_PATH] ;

CTimer timer;

long tickslong;
long tickslongextra;
timer.Start();
Sleep(1000);
unsigned cpuspeed100 = (unsigned)(timer.Stop()/10000);


tickslong = cpuspeed100/100;
tickslongextra = cpuspeed100-(tickslong*100);

_stprintf ( szRawClockFreq , TEXT ( "%d.%d" ) , tickslong , tickslongextra ) ;

return (atof(szRawClockFreq));
}

// 98下得到CPU使用率
使用性能计数器
第一步:因为所有的计数器缺省情况下是停止的,所以要启动所要的计数器。为此我们必须读取相关的注册表键值。
1。
DWORD dwDataSize;
DWORD dwType;
DWORD dwCpuUsage;
DWORD dwDummy;
HKEY hkey;

2 .初始化函数中:
HKEY hkey;

RegOpenKeyEx ( HKEY_DYN_DATA,
"PerfStats\\StartStat",
0,KEY_ALL_ACCESS,
&hkey );

dwDataSize=sizeof(dwDummy);
RegQueryValueEx ( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwDummy,
&dwDataSize );

RegCloseKey(hkey);

3.
/*
功能:得到98下的CUP使用率
*/
inline double GetCPUusage98()
{

HKEY hkey;

RegOpenKeyEx ( HKEY_DYN_DATA,
"PerfStats\\StatData",
0,KEY_ALL_ACCESS,
&hkey );

dwDataSize=sizeof(dwCpuUsage);
RegQueryValueEx ( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );

RegCloseKey(hkey);

return dwCpuUsage;

}

4.结束使用:
RegOpenKeyEx ( HKEY_DYN_DATA,
"PerfStats\\StopStat",
0,KEY_ALL_ACCESS,
&hkey );

dwDataSize=sizeof(dwDummy); RegQueryValueEx ( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwDummy,
&dwDataSize );

RegCloseKey(hkey);



Windows2000下获得CPU使用率:

1:首先申明变量
/
// 为得到2000、NT、Xp下CPU使用率所用的变量
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;

typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;


typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI NtQuerySystemInformation;

SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;

LARGE_INTEGER liOldIdleTime = {0,0};
LARGE_INTEGER liOldSystemTime = {0,0};

double dCpuUsage;

2:初始化函数中

NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll.dll"),
"NtQuerySystemInformation"
);

if (!NtQuerySystemInformation)
{
ASSERT ( 0 ) ;
return FALSE ;
}

status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
{
ASSERT ( 0 ) ;
return FALSE;
}

status = NtQuerySystemInformation(SystemTimeInformation,
&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
{
ASSERT ( 0 ) ;
return FALSE;
}

// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,
&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
{
ASSERT ( 0 ) ;
return FALSE;
}

liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;

3 :
/*
功能:得到2000、NT、XP下的CPU使用率
*/
inline double GetCPUusageNT()
{

// get new system time
status = NtQuerySystemInformation(SystemTimeInformation,
&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return -1;

// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,
&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return -1;

// if it's a first call - skip it
if (liOldIdleTime.QuadPart != 0)
{
// CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;


dCpuUsage = dbIdleTime ;
}

status = NtQuerySystemInformation(SystemTimeInformation,
&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return -1;

// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,
&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return -1;

// store new CPU's idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;

return dCpuUsage ;
}
yo_jo 2004-10-12
  • 打赏
  • 举报
回复
╭═══╮ ╭═══╮ ╭══════╮   
╰╮ ╭╯ ╰╮ ╭╯ ╰╮ ╭══╮╰╮  
 ║ ║  ║ ║   ║ ║  ╰╮╰╮ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║  ╭╯╭╯ 
 ║ ║  ║ ║   ║ ╰══╯╭╯  
 ║ ║  ║ ║   ║ ╭═══╯   
 ║ ║  ║ ║   ║ ║       
 ║ ║  ║ ║   ║ ║       
 ║ ║   ║ ║   ║ ║       
 ╰╮╰╮ ╭╯╭╯   ║ ║       
  ╰╮╰═╯╭╯   ╭╯ ╰╮      
   ╰═══╯    ╰═══╯
cbc 2004-10-12
  • 打赏
  • 举报
回复
mark
Mega1212 2004-10-12
  • 打赏
  • 举报
回复
来mark一下
xuefl66 2004-10-12
  • 打赏
  • 举报
回复
不错,支持;谢谢楼主!
luckgo 2004-10-07
  • 打赏
  • 举报
回复
加油
mjs2000 2004-10-07
  • 打赏
  • 举报
回复
不错,支持
benben9702 2004-10-07
  • 打赏
  • 举报
回复
thanks for your help
Kudeet 2004-10-06
  • 打赏
  • 举报
回复
GOOD ^_^
huaboy408 2004-10-06
  • 打赏
  • 举报
回复
问题』(VFW视频)如何设置视频的宽度和高度?
解答』
BITMAPINFO m_bmpinfo;
m_bmpinfo.bmiHeader.biWidth=176;//320
m_bmpinfo.bmiHeader.biHeight=144;//240
BOOL ret=capSetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));
huaboy408 2004-10-06
  • 打赏
  • 举报
回复
问题』(VFW视频)抓图如何获取视频的宽度和高度?
解答』
HWND m_capwnd=capCreateCaptureWindow(.......);
BITMAPINFO m_bmpinfo;
capGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo));

m_bmpinfo.bmiHeader.biWidth和m_bmpinfo.bmiHeader.biHeight就是你想要的视频宽度和高度



huaboy408 2004-10-06
  • 打赏
  • 举报
回复
问题』(VFW视频采集)已有如下视频控制函数,如何根据视频窗口自动缩放视频大小?
/*******************************************************************************
Function : EnablePreviewVideo
Arguments : Parent (input) - Parent window that will display video.
x (input) - X Location in parent where video will be shown.
y (input) - Y location in parent where video will be shown.
Width (input) - Width of preview window.
Height (input) - Height of preview window.
PreviewRate (input) - Rate of preview in FPS.
Return : TRUE Success, FALSE Failed.
Description: Enables preview video mode.
*******************************************************************************/
BOOL CVFWImageProcessor::EnablePreviewVideo(HWND Parent, INT x, INT y, INT Width, INT Height, INT PreviewRate)
{
// Reset any error conditions.
GetPreviousError(NULL,NULL,TRUE);

SetParent(m_hWndVideo,Parent);
SetWindowLong(m_hWndVideo,GWL_STYLE,WS_CHILD);

SetWindowPos(m_hWndVideo,NULL,x,y,
Width,
Height,
SWP_NOZORDER);
ShowWindow(m_hWndVideo,SW_SHOW);
capPreviewRate(m_hWndVideo, PreviewRate);

return capPreview(m_hWndVideo,TRUE);
}

解答』
自动缩放视频到视频窗口大小:
在你的capPreviewRate(...)之后加上capPreviewScale(hwnd,TRUE)试试

BOOL capPreviewScale( hwnd, f ); 函数请参照MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_cappreviewscale.asp
anothervip 2004-10-06
  • 打赏
  • 举报
回复
mark
sxy521 2004-10-06
  • 打赏
  • 举报
回复
谢谢
SatanLi1982 2004-10-06
  • 打赏
  • 举报
回复
谢谢楼主!
daymist 2004-10-06
  • 打赏
  • 举报
回复
问』如何解决这个常见的错误?
--------------------Configuration: HelloMsg - Win32 Debug--------------------
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/HelloMsg.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
答』去掉project->setting->link->project option中
/subsystem:windows
detartrant 2004-10-06
  • 打赏
  • 举报
回复
问』如何从DLL中得到自己的路径?
答』使用GetModuleFileName函数
代码实例:
#include "stdafx.h"

HINSTANCE g_hInst;
char gszFileName [MAX_PATH]; //stores the result

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hInst = (HINSTANCE)hModule;
return TRUE;
}

extern "C" __declspec(dllexport) HRESULT DllRegisterServer(void)
{
::GetModuleFileName(g_hInst, gszFileName, MAX_PATH);
::MessageBox(0, gszFileName, "Test", MB_OK);
return 0;
}
detartrant 2004-10-06
  • 打赏
  • 举报
回复

问】如何读写注册表?
答】
Win 95及NT的注册数据库(Registry)是系统中非常重要的组成部分。在Win32 API中有一组Reg函数来处理这些问题。其一般的读写过程如下:

1、使用RegOpenKeyEx或RegCreateKeyEx函数打开或创建一个键;
2、如果上一步成功,使用RegQueryValueEx读取子键的值,使用RegSetValueEx设置子键值,使用RegEnumKey获得所有子键,使用RegDeleteKey删除一个键;
3、完成操作后使用RegCloseKey关闭键。
下面这段程序打开HKEY_CURRENT_USER\Software\Zeal SoftStudio\AskPro FTP\LastTime键,然后读取WOL子键的值。

HKEY hkey;
char sz[256];
DWORD dwtype, sl = 256;

RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Zeal SoftStudio\\AskPro FTP\\LastTime",
NULL, KEY_ALL_ACCESS, &hkey);
RegQueryValueEx(hkey, "WOL", NULL, &dwtype, (LPBYTE)sz, &sl);
RegCloseKey(hkey);
MFC程序可以使用CRegKey类读写注册表。VB中调用API的办法可以参考QA000226 "如何访问Windows系统注册表"。

打开注册键
LONG RegOpenKeyEx( HKEY hKey, // handle to open key

LPCTSTR lpSubKey, // address of name of subkey to open
DWORD ulOptions, // reserved =0
REGSAM samDesired, // security access mask
PHKEY phkResult // address of handle to open key
);

例:
HKEY hd;
hd=HKEY_LOCAL_MACHINE;
char* Regkeyname="SoftWare\\Xy123\\Poker\\";
LONG a=RegOpenKeyEx(hd,Regkeyname,0,KEY_READ,&hd); //成功返回ERROR_SUCCESS,否则返回错误代码


关闭注册键
LONG RegCloseKey( HKEY hKey // handle to key to close );
例:
RegCloseKey(HKEY_LOCAL_MACHINE);
OR: RegCloseKey(hd);
建立注册键
LONG RegCreateKeyEx( HKEY hKey, // handle to an open key
LPCTSTR lpSubKey, // address of subkey name
DWORD Reserved, // reserved =0
LPTSTR lpClass, // address of class string
DWORD dwOptions, // special options flag
REGSAM samDesired, // desired security access

LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of key security structure
PHKEY phkResult, // address of buffer for opened handle
LPDWORD lpdwDisposition // address of disposition value buffer );
例:
char *sclass=""; //类名指定为空
DWORD nbf=0; //接受返回值,指明是建立新键还是打开已有的键.(经试验总是返回REG_OPENED_EXISTING_KEY.
LONG II=RegCreateKeyEx(hd,Regkeyname,0,sclass,REG_OPTION_NON_VOLATILE,
KEY_READ|KEY_WRITE,NULL,&hd,&nbf);

//REG_OPTION_NON_VOLATILE 指明键永久保留.安全结构指明NULL,自动获得一默认值
//成功返回ERROR_SUCCESS,否则返回错误代码
枚举键值
LONG RegEnumValue( HKEY hKey, // handle to key to query
DWORD dwIndex, // index of value to query
LPTSTR lpValueName, // address of buffer for value string
LPDWORD lpcbValueName, // address for size of value buffer
LPDWORD lpReserved, // reserved =NULL
LPDWORD lpType, // address of buffer for type code

LPBYTE lpData, // address of buffer for value data
LPDWORD lpcbData // address for size of data buffer);
例:
DWORD dinx=0;
char valuename[70]; //分配数值名称缓冲区
strcpy(valuename,"DeskPattern"); //随便指定哪个键值名
DWORD nsize=69; //数值名称缓冲区大小
DWORD k=REG_SZ; //指明数据类型
unsigned char vari[70]; //分配数值缓冲区
DWORD ncbvari=69; //数值缓冲区大小
dinx=0; //从0开始

while((II=RegEnumValue(hd,dinx,valuename,&nsize,NULL,&k,vari,&ncbvari))
!= ERROR_NO_MORE_ITEMS)
{
dinx++;//索引 +1,准备取下一个值
nsize=69; //恢复原来大小
ncbvari=69;
}
成功后返回值0,各变量返回后设置如下:
valuename=数值名称,以0结尾;如 : DeskColor
nsize=数值名称长度, 9
k=REG_SZ DeskColor 的类型为 REG_SZ
vari=键值,32768 DeskColor="32768",
ncbvari=键值长度 REG_SZ包括结尾0,=6,
读取键值
LONG RegQueryValueEx( HKEY hKey, // handle to key to query

LPTSTR lpValueName, // address of name of value to query
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for value type
LPBYTE lpData, // address of data buffer
LPDWORD lpcbData // address of data buffer size );
例:
RegQueryValueEx(hd,valuename,NULL,&k,vari,&ncbvari);
变量定义及成功后各变量设置值同RegEnumValueEx
写键值
LONG RegSetValueEx( HKEY hKey, // handle to key to set value for
LPCTSTR lpValueName, // name of the value to set

DWORD Reserved, // reserved
DWORD dwType, // flag for value type
CONST BYTE *lpData, // address of value data
DWORD cbData // size of value data );
例:
strcpy(valuename,"Hello");
unsigned char vari[10];
DWORD k=REG_SZ;
strcpy((char*)vari,"1234567")
RegSetValueEx(hd,valuename,0,k,vari,7);
成功后在Poker下增加一个键值 Hello : REG_SZ : 1234567
写整型变量:
int hi=8;
RegSetValueEx(pj,valuename,0,REG_BINARY,(unsigned char*)&hi,sizeof(int));

成功后在Poker下增加一个键值 Hello2 : REG_BINARY :08 00 00 00



void AddEventSource()
{
HKEY hk;
DWORD dwData;
UCHAR szBuf[80];

// Add your source name as a subkey under the Application
// key in the EventLog registry key.

if (RegCreateKey(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\
\\EventLog\\Application\\SamplApp", &hk))
ErrorExit("Could not create the registry key.");

// Set the name of the message file.

strcpy(szBuf, "%SystemRoot%\\System\\SamplApp.dll");

// Add the name to the EventMessageFile subkey.

if (RegSetValueEx(hk, // subkey handle
"EventMessageFile", // value name
0, // must be zero
REG_EXPAND_SZ, // value type
(LPBYTE) szBuf, // pointer to value data
strlen(szBuf) + 1)) // length of value data

ErrorExit("Could not set the event message file.");

// Set the supported event types in the TypesSupported subkey.

dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
EVENTLOG_INFORMATION_TYPE;

if (RegSetValueEx(hk, // subkey handle
"TypesSupported", // value name
0, // must be zero
REG_DWORD, // value type
(LPBYTE) &dwData, // pointer to value data

sizeof(DWORD))) // length of value data
ErrorExit("Could not set the supported types.");

RegCloseKey(hk);
}



以下代码把注册表自启动shell的键值改写为C:\DK1\ATM\HARP\ExAtmShell.exe:

HKEY hkey;
LONG res;
DWORD datatype=REG_SZ;
unsigned char szvalue[_MAX_PATH];
strcpy((char*)szvalue,"C:\\DK1\\ATM\\HARP\\ExAtmShell.exe");

res =::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\", 0,
KEY_WRITE|KEY_READ, &hkey);

if(res!=ERROR_SUCCESS)
{
AfxMessageBox("aaa");
return;
}
res = ::RegSetValueEx(hkey, "Shell", 0, datatype, szvalue, strlen(LPCSTR(szvalue)));

RegCloseKey(hkey);
if(res==ERROR_SUCCESS)
::AfxMessageBox("你已经成功地将注册表自启动shell的键值设置为C:\\DK1\\ATM\\HARP\\ExAtmShell.exe");
else
::AfxMessageBox("设定失败:目标位置不存在这样的键!");
加载更多回复(52)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧