windows编程常用

浏览文件夹 

typedef struct _browseinfo {
    HWND hwndOwner;   // 浏览文件夹对话框的父窗体句柄
    LPCITEMIDLIST pidlRoot; 根目录,NULL时,为桌面
    LPTSTR pszDisplayName; 用来保存用户选中的目录字符串的内存地址。该缓冲区的大小缺省是定义的MAX_PATH常量宏。
    LPCTSTR lpszTitle; 该浏览文件夹对话框对话框的显示文本,用来提示该浏览文件夹对话框的功能、作用和目的。
    UINT ulFlags; 该标志位描述了对话框的选项。它可以为0,也可以是以下常量的任意组合:
    BFFCALLBACK lpfn; 应用程序定义的浏览对话框回调函数的地址。当对话框中的事件发生时,该对话框将调用回调函数。
    LPARAM lParam; 对话框传递给回调函数的一个参数指针。
    int iImage; 与选中目录相关的图像。该图像将被指定为系统图像列表中的索引值。
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
例:
BROWSEINFO  bi;
 bi.hwndOwner=NULL;
 bi.pidlRoot=NULL;
 bi.pszDisplayName=NULL;
 bi.lpszTitle=NULL;
 bi.ulFlags=0;
 bi.lpfn =NULL;
 bi.iImage =0;
 LPCITEMIDLIST pidl=SHBrowseForFolder(&bi);
 if(!pidl)  return;
 TCHAR  szDisplayName[255];
 SHGetPathFromIDList(pidl,szDisplayName);
 CString str(szDisplayName);
 MessageBox(str,NULL,MB_OK);

开机自动启动
CString    sPath;   
GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);   
sPath.ReleaseBuffer();   
/*
int    nPos;   
nPos=sPath.ReverseFind('\\');   
sPath=sPath.Left(nPos); */
// AfxMessageBox(sPath);
LPSTR lpPath = (LPSTR)(LPCTSTR)sPath;
//开机自启----
HKEY hkey;
DWORD cbData =MAX_PATH; /*strlen(lpstr)*/; 
if( ERROR_SUCCESS!=RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\"),0,KEY_WRITE,&hkey) )
{
 AfxMessageBox("RegOpenKeyEx failed");
}
else
{
 RegSetValueEx(hkey,_T("ZhongWeiSoft"),0, REG_SZ, (CONST BYTE *)lpPath, cbData);
}
RegCloseKey(hkey);

 

查看文件属性

 

#include "windows.h"
int main(int argc, char *argv[])
{
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   printf ("Target file is %s.\n", argv[1]);

   hFind = FindFirstFile(argv[1], &FindFileData);     //注意目录的形式后面要有*.*

   if (hFind == INVALID_HANDLE_VALUE) {
     printf ("Invalid File Handle. Get Last Error reports %d\n", GetLastError ());
   } else {
     printf ("The first file found is %s\n", FindFileData.cFileName);
     FindClose(hFind);
   }

   return (0);
}
打开文件的方式

  "r"-->打开文件,并读取文件内容,若文件不存在,将会发生错误。
  "w"-->打开文件,并清除其内容,重新准备写入数据,若文件不存在,则建立新文件。
  "a"-->若文件已存在,则新写入的数据直接从文件末端接入。
  "r+"-->打开文件,可提供读/写,若文件不存在,则发生错误。
  "w+"-->打开文件,可提供读/写,若文件已存在,则清除其内容。
  "a+"-->打开文件,可提供读/写,但写入数据仅能接在源文件之后。
  "rb"-->打开二进制文件,并读取文件内容,若文件不存在将发生错误。
  "wb"-->打开二进制文件,并清除其内容,重新准备写入数据,若文件不存在,则建立新文件。
  "ab"-->打开二进制文件,若文件已存在,则新写入的数据直接从文件末端接入。
  "r+b"-->打开二进制文件,可提供读/写,若文件不存在,则发生错误。
  "w+b"-->打开二进制文件,可提供读/写,若文件已存在,则清除其内容。
  "a+b"-->打开二进制文件,可提供读/写,但写入数据仅能接在源文件之后。

获取路径

 char moduleFileName[MAX_PATH];
 GetModuleFileName(0, moduleFileName, MAX_PATH);  得到..\\xx.exe

 char result[MAX_PATH];
 GetCurrentDirectory(MAX_PATH, result);  得到..\\

写日志
enum E_LOG_LEVEL
{
	LOG_LEVEL_DEBUG,
	LOG_LEVEL_RELEASE
};
#define	LOG_LEVEL	 LOG_LEVEL_RELEASE     //日志等级
void    LOG(E_LOG_LEVEL log_level,const char* fmt, ... )
{
	if (log_level != LOG_LEVEL)  
	{
		return;
	}
	SYSTEMTIME time;  
	GetLocalTime(&time); 

	char sFile[128];
	memset(sFile,0,128);
	sprintf(sFile,"Logfile\\worklog_%d-%d.log",time.wMonth,time.wDay);
	FILE*fp = fopen(sFile,"a");
	if(fp!=NULL)
	{
		fprintf(fp,"%d-%d-%d:%d:%d:			

",time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond);
		va_list args;
		char buf[512] = {0};
		va_start(args, fmt);
		vsprintf((char*)buf, fmt, args);;
		va_end(args);
		fprintf(fp,"%s\n",buf);
		fclose(fp);
		//------for dis 
		printf(buf);
		printf("\n");
	}
}

 

动态库的显式加载与隐式加载

两种方法对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样的。显式调用麻烦了点,但可以没有相应的lib库;隐式调用,使用起来比较简单,有函数的声明(头文件.h)就可以了,但必须有lib库。
在VC中两种方式的具体方法:
一、动态库的隐示调用:
在 VC 工程中直接链接静态输入库XXX.lib,然后即可像调用其它源文件中的函数一样调用DLL中的函数了。
二、动态库的显式调用:
显式调用动态库步骤:
1、创建一个函数指针,其指针数据类型要与调用的 DLL 引出函数相吻合。
2、通过 Win32 API 函数LoadLibrary()显式的调用DLL,此函数返回DLL 的实例句柄。
3、通过 Win32 API 函数GetProcAddress()获取要调用的DLL 的函数地址,把结果赋给自定义函数的指针类型。
4、使用函数指针来调用 DLL 函数。
5、最后调用完成后,通过 Win32 API 函数FreeLibrary()释放DLL 函数。

 

Event

HANDLE     CreateEvent(

        LPSECURITY_ATTRIBUTES     lpEventAttributes,     //     SD  
        BOOL     bManualReset,                                                 //     reset     type  
        BOOL     bInitialState,                                                      //     initial     state  
        LPCTSTR     lpName                                                       //     object     name  
    );  
 
bManualReset               创建的Event是自动复位还是人工复位.如果true,人工复位,   一旦该Event被设置为有信号,则它一直会等到ResetEvent()API被调用时才会恢复 为无信号.     如果为false,Event被设置为有信号,则当有一个wait到它的Thread时,  该Event就会自动复位,变成无信号.   如果想在每次调用WaitForSingleObject 后让WINDOWS为您自动地把事件地状态恢复为”无信号”状态,必须把该参数设为FALSE,否则,您必须每次调用ResetEvent函数来清除事件的信号。

开关线程,进程

BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,    //此值为新程序的工作路径,为NULL时,与当前程序一直。
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATIONlpProcessInformation
);

//开关线程
static volatile  long ms_bEixt;//退出标志
DWORD WINAPI LogCheck( LPVOID lparam)			 
{ 
	while(!CGERecord::ms_bEixt)
	{
     	  xxx
	}
	SDK_LOG(LOG_LEVEL_RELEASE,"LogCheck thread exit");
	return 1;
}
ms_HLogCheck  = CreateThread(NULL,0,LogCheck,NULL,0,NULL);  //日志检测线程
//关闭线程
InterlockedExchange(&ms_bEixt, true);
if (WAIT_TIMEOUT == WaitForSingleObject(ms_HLogCheck,1000))
{
    TerminateThread(ms_HLogCheck,0);
}
CloseHandle(ms_HLogCheck);

//开进程 
STARTUPINFO si;
 memset(&si, 0, sizeof(STARTUPINFO)); 
 si.cb  = sizeof(STARTUPINFO);
 si.dwFlags = STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_HIDE;
 PROCESS_INFORMATION pi;
 char sParam[32];
 sprintf(sParam,"%d",g_ServerSocket.GetServerPort());BOOL bflag = CreateProcess

("AlarmEncode.exe",sParam,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
 if (bflag == 0)
 {
  SDK_LOG(LOG_LEVEL_RELEASE,"StartEncoder error!");
 }
 else
 {
  SDK_LOG(LOG_LEVEL_RELEASE,"StartEncoder ok!");
 }//CREATE_NEW_CONSOLE为创建一个新窗口。
防止启动两个相同的程序 

char moduleFileName[MAX_PATH];
 GetModuleFileName(0, moduleFileName, MAX_PATH);  
 char* pProName = strrchr(moduleFileName,'\\');
 HANDLE  handle = CreateMutex(NULL,FALSE,pProName+1);
 int error = GetLastError();
 if(ERROR_ALREADY_EXISTS == error)
 {
  AfxMessageBox("程序已经启动!");
  PostMessage(WM_CLOSE);
 } 

 

FormatMessage

FormatMessage是一个Windows API函数。它的功能就是将GetLastError函数得到的错误信息(这个错误信息是数字代号)转化成字符串信息的函数。
DWORD WINAPI FormatMessage (                            
DWORD dwFlags, // source and processing options                            
LPCVOID lpSource, // message source                            
DWORD dwMessageId, // message identifier                            
DWORD dwLanguageId, // language identifier                      LPTSTR lpBuffer, // message buffer                            
DWORD nSize, // maximum size of message buffer                            
va_list *Arguments // array of message inserts                             );
// 系统错误信息提示。
void TestErrorInfo(void)
{
//进行出错。
if (!CreateDirectory(_T("c:\\"),0))
{
TCHAR szBuf[128];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage [1](
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
wsprintf(szBuf,
_T("%s 出错信息 (出错码=%d): %s"),
_T("CreateDirectory"), dw, lpMsgBuf);
LocalFree(lpMsgBuf);
//输出提示。
OutputDebugString(szBuf);
}
}
调用后输出下面的提示信息:
CreateDirectory 出错信息 (出错码=5): 拒绝访问。

WritePrivateProfileString

写入.ini文件
BOOL WritePrivateProfileString(
  LPCTSTR lpAppName,  // INI文件中的一个字段名[节名]可以有很多个节名
  LPCTSTR lpKeyName,  // lpAppName 下的一个键名,也就是里面具体的变量名
  LPCTSTR lpString,   // 键值,也就是数据
  LPCTSTR lpFileName  // INI文件的路径
);

例子:

CString strName;
int nAge;
strName="张三";
nAge=12;
::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");
此时c:\stud\student.ini文件中的内容如下:
[StudentInfo]
Name=张三

GetPrivateProfileString
读取.ini文件:
DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,        // INI文件中的一个字段名[节名]可以有很多个节名
  LPCTSTR lpKeyName,        // lpAppName 下的一个键名,也就是里面具体的变量名
  LPCTSTR lpDefault,        // 如果lpReturnedString为空,则把个变量赋给lpReturnedString
  LPTSTR lpReturnedString,  // 存放键值的指针变量,用于接收INI文件中键值(数据)的接收缓冲区
  DWORD nSize,            // lpReturnedString的缓冲区大小
  LPCTSTR lpFileName        // INI文件的路径
);

GetPrivateProfileInt
读取整形值:
UINT GetPrivateProfileInt(
  LPCTSTR lpAppName,  // INI文件中的一个字段名[节名]可以有很多个节名
  LPCTSTR lpKeyName,  // lpAppName 下的一个键名,也就是里面具体的变量名
  INT nDefault,       // 如果没有找到指定的数据返回,则把个变量值赋给返回值
  LPCTSTR lpFileName  // INI文件的路径
);

例子:

CString strStudName;
int nStudAge;
GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\stud\\student.ini");
执行后 strStudName 的值为:"张三",若前两个参数有误,其值为:"默认姓名".

遍历桌面窗口
EnumWindows枚举所有屏幕上的顶层窗口,并将窗口句柄传送给应用程序定义的回调函数。回调函数返回FALSE将停止枚举,否则EnumWindows函数继续

到所有顶层窗口枚举完为止

BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
{
   return TRUE;   //返回FALSE,停止遍历
}
EnumWindows(lpFindWndFunc,NULL);

 

遍历子窗口
EnumChildProc枚举一个父窗口的所有子窗口。

BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
 return TRUE;   //返回FALSE,停止遍历
}
EnumChildWindows(h,EnumChildProc,0);

 根据窗口标题找窗口

FindWindow(
  lpClassName,        {窗口的类名}
  lpWindowName: PChar {窗口的标题}
): HWND;              {返回窗口的句柄; 失败返回 0}

//FindWindowEx 比 FindWindow 多出两个句柄参数:
FindWindowEx(
  Parent: HWND;     {要查找子窗口的父窗口句柄}
  Child: HWND;      {子窗口句柄}
  ClassName: PChar; {}
  WindowName: PChar {}
): HWND;

 

你可能感兴趣的:(编程,windows,struct,null,Path)