VC++ 对进程各种操作函数
- 格式:doc
- 大小:41.50 KB
- 文档页数:6
VC窗口处理函数1.HWND CreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HANDLE hlnstance,LPVOID lpParam);参数lpClassName指向一个空结束的字符串或整型数atom。
如果该参数是一个整型量,它是由此前调用theGlobalAddAtom函数产生的全局量。
这个小于0xC000的16位数必须是lpClassName参数字的低16位,该参数的高位必须是0。
如果lpClassName是一个字符串,它指定了窗口的类名。
这个类名可以是任何用函数RegisterClassEx注册的类名,或是任何预定义的控制类名。
请看说明部分的列表。
LPWindowName指向一个指定窗口名的空结束的字符串指针。
如果窗口风格指定了标题条,由lpWindowName指向的窗口标题将显示在标题条上。
当使用Createwindow函数来创建控制例如按钮,选择框和静态控制时,可使用lpWindowName来指定控制文本。
dwStyle指定创建窗口的风格。
该参数可以是下列窗口风格的组合再加上说明部分的控制风格。
风格意义:WS_BORDER:创建一个单边框的窗口。
WS_CAPTION:创建一个有标题框的窗口(包括WS_BODER风格)。
WS_CHILD:创建一个子窗口。
这个风格不能与WS_POPUP风格合用。
WS_CHLDWINDOW:与WS_CHILD相同。
WS_CLIPCHILDREN:当在父窗口内绘图时,排除子窗口区域。
在创建父窗口时使用这个风格。
WS_CLlPBLINGS;排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到WM_PAINT消息时,WS_CLIPSIBLINGS 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。
Visual C++中函数调用方式浅探我们知道在进行函数调用时,有几种调用方法,分为C式,Pascal式。
在C和C++中C式调用是缺省的,除非特殊声明。
二者是有区别的,下面我们用实例说明一下:1. __cdecl :C和C++缺省调用方式例子:void Input( int &m,int &n);/*相当于void __cdecl Input(int &m,int &n);*/以下是相应的汇编代码:00401068 lea eax,[ebp-8] ;取[ebp-8]地址(ebp-8),存到eax0040106B push eax ;然后压栈0040106C lea ecx,[ebp-4] ;取[ebp-4]地址(ebp-4),存到ecx0040106F push ecx ;然后压栈00401070 call @ILT+5(Input) (0040100a);然后调用Input函数00401075 add esp,8 ;恢复栈从以上调用Input函数的过程可以看出:在调用此函数之前,首先压栈ebp-8,然后压栈ebp-4,然后调用函数Input,最后Input函数调用结束后,利用esp+8恢复栈。
由此可见,在C语言调用中默认的函数修饰_cdecl,由主调用函数进行参数压栈并且恢复堆栈。
下面看一下:地址ebp-8和ebp-4是什么?在VC的VIEW下选debug windows,然后选Registers,显示寄存器变量值,然后在选debug windows下面的Memory,输入ebp-8的值和ebp-4的值(或直接输入ebp-8和-4),看一下这两个地址实际存储的是什么值,实际上是变量n 的地址(ebp-8),m的地址(ebp-4),由此可以看出:在主调用函数中进行实参的压栈并且顺序是从右到左。
另外,由于实参是相应的变量的引用,也证明实际上引用传递的是变量的地址(类似指针)。
VC++中进程与多进程管理的方法作者:顾洋来源:《当代教育科学研究》2013年第02期实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,如果没有,进程将成功创建并设置标识实例已经存在的标记。
此后再创建进程时将会通过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。
具体可以采取内存映射文件、有名事件量、有名互斥量以及全局共享变量等多种方法来实现。
下面就分别对其中具有代表性的有名互斥量和全局共享变量这两种方法进行介绍:进程只是提供了一段地址空间和内核对象,其运行是通过在其地址空间内的主线程来体现的。
当主线程的进入点函数返回时,进程也就随之结束。
这种进程的终止方式是进程的正常退出,进程中的所有线程资源都能够得到正确的清除。
除了这种进程的正常推出方式外,有时还需要在程序中通过代码来强制结束本进程或其他进程的运行。
ExitProcess()函数即可在进程中的某个线程中使用,并将立即终止本进程的运行。
ExitProcess()函数原型为:VOID ExitProcess(UINT uExitCode);其参数uExitCode为进程设置了退出代码。
该函数具有强制性,在执行完毕后进程即已经被结束,因此位于其后的任何代码将不能被执行。
虽然ExitProcess()函数可以在结束进程的同时通知与其相关联的动态链接库,但是由于它的这种执行的强制性,使得ExitProcess()函数在使用上将存在有安全隐患。
例如,如果在程序调用ExitProcess()函数之前曾用new操作符申请过一段内存,那么将会由于ExitProcess()函数的强制性而无法通过delete操作符将其释放,从而造成内存泄漏。
有鉴于ExitProcess()函数的强制性和不安全性,在使用时一定要引起注意。
ExitProcess()只能强制执行本进程的退出,如果要在一个进程中强制结束其他的进程就要用TerminateProcess()来实现。
VC从一个程序中启动和关闭另一个程序今天正在编写的程序是一个插件(PlugIn)。
插件其实就是一个动态链接库,可以被主程序装入内存中,并调用插件中按照主程序规定编写的函数。
由于插件受制于主程序,因此我必须另外提供一个程序可以扩展插件的功能。
于是乎,我就编写了一个更加复杂的程序来完成更多的功能,但是为了使这个程序可以看起来是和使用插件的程序象是集成在一起的,就必须在启动插件程序的过程中,也同时启动我后来编写的程序,并且还要在插件主程序关闭之前,将我编写的程序也关闭。
为了实现这一目的,ShellExecuteEx()以及FindWindow()就被使用了。
ShellExecute()和ShellExecuteEx()被设计可以通过系统来启动一个程序。
为了可以正确执行程序,那么就要为ShellExecute()和ShellExecuteEx()指定正确的目录和程序名。
下面是一个使用ShellExecuteEx的例子:SHELLEXECUTEINFO ShExecInfo;ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);ShExecInfo.fMask = NULL;ShExecInfo.hwnd = NULL;ShExecInfo.lpVerb = NULL;ShExecInfo.lpFile = _T(“C:\\MyProgram.exe“); // 执行的程序名ShExecInfo.lpParameters = NULL;ShExecInfo.lpDirectory = NULL;ShExecInfo.nShow = SW_MAXIMIZE; // 全屏显示这个程序ShExecInfo.hInstApp = NULL;ShellExecuteEx(&ShExecInfo);如果ShellExecuteEx()没有执行正确,GetLastError 会帮助你找到问题所在。
CombineRgn将两个区域组合为一个新区域CombineTransform驱动世界转换。
它相当于依顺序进行两次转换CreateCompatibleDC创建一个与特定设备场景一致的内存设备场景CreateDC为专门设备创建设备场景CreateEllipticRgn创建一个椭圆CreateEllipticRgnIndirect创建一个内切于特定矩形的椭圆区域CreateIC为专用设备创建一个信息场景CreatePolygonRgn创建一个由一系列点围成的区域CreatePolyPolygonRgn创建由多个多边形构成的区域。
每个多边形都应是封闭的CreateRectRgn创建一个矩形区域CreateRectRgnIndirect创建一个矩形区域CreateRoundRectRgn创建一个圆角矩形DeleteDC删除专用设备场景或信息场景,释放所有相关窗口资源DPtoLP将点阵从设备坐标转换到专用设备场景逻辑坐标EqualRgn确定两个区域是否相等ExcludeClipRect从专用设备场景的剪裁区中去掉一个矩形区。
矩形内不能进行绘图ExcludeUpdateRgn从专用设备场景剪裁区去掉指定窗口的刷新区域ExtCreateRegion根据世界转换修改区域ExtSelectClipRgn将指定区域组合到设备场景的当前剪裁区FillRgn用指定刷子填充指定区域FrameRgn用指定刷子围绕指定区域画一个外框GetBoundsRect获取指定设备场景的边界矩形GetClipBox获取完全包含指定设备场景剪裁区的最小矩形GetClipRgn获取设备场景当前剪裁区GetDC获取指定窗口的设备场景GetDCEx为指定窗口获取设备场景。
相比GetDC,本函数提供了更多的选项GetDCOrgEx获取指定设备场景起点位置(以屏幕坐标表示)GetDeviceCaps根据指定设备场景代表的设备的功能返回信息GetGraphicsMode确定是否允许增强图形模式(世界转换)GetMapMode为特定设备场景调入映象模式GetRegionData装入描述一个区域信息的RgnData结构或缓冲区GetRgnBox获取完全包含指定区域的最小矩形GetUpdateRgn确定指定窗口的刷新区域。
VC创建进程CreateProcess的⽅法本⽂实例讲述了VC创建进程CreateProcess的⽅法。
分享给⼤家供⼤家参考。
具体实现⽅法如下:#include "stdafx.h"#include <windows.h>#include <stdio.h>int main (int argc,char* argv[]){char szCommandLine[]="cmd";STARTUPINFO si={sizeof(si)};PROCESS_INFORMATION pi;si.dwFlags=STARTF_USESHOWWINDOW; //制定wShowWindow成员si.wShowWindow=TRUE; //为真,显⽰进程的主窗⼝BOOL bRet=::CreateProcess(NULL,//不在此指定可执⾏⽂件的⽂件名szCommandLine, //命令⾏参数NULL,//默认进程的安全性NULL,//默认线程的安全性FALSE,//指定当前进程内的句柄不可以被⼦进程继承CREATE_NEW_CONSOLE,//为新进程创建⼀个新的控制台窗⼝NULL,//使⽤本进程的环境变量NULL,//使⽤本进程的驱动器和⽬录&si,&pi);if (bRet){//既然我们不使⽤两个句柄,最好是⽴刻将他们关闭::CloseHandle(pi.hThread);::CloseHandle(pi.hProcess);printf("新的进程的进程ID号:%d\n",pi.dwProcessId);printf("新进程的主线程ID号:%d\n",pi.dwThreadId);}return 0;}希望本⽂所述对⼤家的VC程序设计有所帮助。
Visual C++是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快。
但在科学计算方面函数库显得不够丰富、读取、显示数据图形不方便。
Matlab是一款将数值分析、矩阵计算、信号处理和图形显示结合在一起,包含大量高度集成的函数可供调用,适合科学研究、工程设计等众多学科领域使用的一种简洁、高效的编程工具。
不过由于Matlab使用的是解释性语言,大大限制了它的执行速度和应用场合。
基于VC和Matlab混合编程是很多熟悉VC++编程而又需要进行科学计算、数据仿真的科研人员常用的一种方式,其中最简单也最直接的方法就是调用Matlab引擎。
本文以下部分将详细介绍通过VC++6.0调用Matlab6.5引擎来达到VC++与Matlab数据共享编程的方法。
1. 什么是Matlab引擎所谓Matlab引擎(engine),是指一组Matlab提供的接口函数,支持C/C++、Fortran等语言,通过这些接口函数,用户可以在其它编程环境中实现对Matlab 的控制。
可以主要功能有:★打开/关闭一个Matlab对话;★向Matlab环境发送命令字符串;★从Matlab环境中读取数据;★向Matlab环境中写入数据。
与其它各种接口相比,引擎所提供的Matlab功能支持是最全面的。
通过引擎方式,应用程序会打开一个新的Matlab进程,可以控制它完成任何计算和绘图操作。
对所有的数据结构提供100%的支持。
同时,引擎方式打开的Matlab进程会在任务栏显示自己的图标,打开该窗口,可以观察主程序通过engine方式控制Matlab运行的流程,并可在其中输入任何Matlab命令。
实际上,通过引擎方式建立的对话,是将Matlab以ActiveX控件方式启动的。
在Matlab初次安装时,会自动执行一次:matlab /regserver将自己在系统的控件库中注册。
如果因为特殊原因,无法打开Matlab引擎,可以在Dos命令提示符后执行上述命令,重新注册。
C语言文件操作常用函数详解C语言文件操作是对计算机中的文件进行读取、写入、修改等操作的一种方式。
在C语言中,文件操作是通过文件指针来实现的。
文件指针是一个指向文件的地址,通过它可以进行文件的读写操作。
接下来,我将详细介绍C语言文件操作常用的函数。
1. fopen函数:用于打开文件,创建文件指针。
它的原型在stdio.h 头文件中,语法格式如下:FILE *fopen(const char *filename, const char *mode);其中,filename是文件名,可以是相对路径或绝对路径;mode是打开模式,常用的有"r"(以只读方式打开)、"w"(以只写方式打开,若文件不存在,则创建)和"a"(以追加方式打开)。
2. fclose函数:用于关闭文件,释放文件指针。
它的原型也在stdio.h头文件中,语法格式如下:int fclose(FILE *stream);其中,stream是文件指针,表示要关闭的文件。
3. fgetc和getc函数:用于从文件中读取一个字符。
它们的原型在stdio.h头文件中,语法格式如下:int fgetc(FILE *stream);int getc(FILE *stream);其中,stream是文件指针,表示要读取字符的文件。
4. fgets函数:用于从文件中读取一行字符。
它的原型在stdio.h 头文件中,语法格式如下:char *fgets(char *str, int n, FILE *stream);其中,str是用于存储读取字符的数组,n是最大读取字符数,stream是文件指针。
5. fputc和putc函数:用于向文件中写入一个字符。
它们的原型在stdio.h头文件中,语法格式如下:int fputc(int c, FILE *stream);int putc(int c, FILE *stream);其中,c是要写入的字符,stream是文件指针。
1 引用是C++引入的新语言特性,是C++常用的一个重要内容之一,正确、灵活地使用引用,可以使程序简洁、高效。我在工作中发现,许多人使用它仅仅是想当然,在某些微妙的场合,很容易出错,究其原由,大多因为没有搞清本源。故在本篇中我将对引用进行详细讨论,希望对大家更好地理解和使用引用起到抛砖引玉的作用。 一、引用简介
引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:类型标识符 &引用名=目标变量名; 【例1】:int a; int &ra=a; //定义引用ra,它是变量a的引用,即别名 说明: (1)&在此不是求地址运算,而是起标识作用。 (2)类型标识符是指目标变量的类型。 (3)声明引用时,必须同时对其进行初始化。 (4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
ra=1; 等价于 a=1; (5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。
(6)不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。
二、引用应用 1、引用作为参数 引用的一个重要作用就是作为函数的参数。以前的C语言中函数参数传递是值传递,如果有大块数据作为参数传递的时候,采用的方案往往是指针,因为这样可以避免将整块数据全部压栈,可以提高程序的效率。但是现在(C++中)又增加了一种同样有效率的选择(在某些特殊情况下又是必须的选择),就是引用。
【例2】: 2
void swap(int &p1, int &p2) //此处函数的形参p1, p2都是引用 { int p; p=p1; p1=p2; p2=p; }
为在程序中调用该函数,则相应的主调函数的调用点处,直接以变量作为实参进行调用即可,而不需要实参变量有任何的特殊要求。如:对应上面定义的swap函数,相应的主调函数可写为:
//获取进程路径 CString GetProcessPath( DWORD idProcess ) { // 获取进程路径 CString sPath; // 打开进程句柄 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, idProcess ); if( NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; // 获取路径 if( EnumProcessModules( hProcess, &hMod, sizeof( hMod ), &cbNeeded ) ) { DWORD dw = GetModuleFileNameEx( hProcess, hMod, sPath. GetBuffer( MAX_PATH ), MAX_PATH ); sPath.ReleaseBuffer(); } CloseHandle( hProcess ); } return( sPath ); }
//获取进程优先级 CString GetProcessPriority(HANDLE hProcess) { char sz1[10] = "NORMAL"; char sz2[10] = "IDLE"; char sz3[10] = "REALTIME"; char sz4[10] = "HIGH"; char sz5[10] = "NULL"; char sz6[15] = "ABOVENORMAL"; char sz7[15] = "BELOWNORMAL";
//进程优先级返回 if(GetPriorityClass(hProcess) == NORMAL_PRIORITY_CLASS) return sz1; if(GetPriorityClass(hProcess) == IDLE_PRIORITY_CLASS) return sz2; if(GetPriorityClass(hProcess) == REALTIME_PRIORITY_CLASS) return sz3; if(GetPriorityClass(hProcess) == HIGH_PRIORITY_CLASS) return sz4; if(GetPriorityClass(hProcess) == ABOVE_NORMAL_PRIORITY_CLASS) return sz6; if(GetPriorityClass(hProcess) == BELOW_NORMAL_PRIORITY_CLASS) return sz7; else return sz5; }
//终止进程主函数 void TerminateProcessID(DWORD dwID) { HANDLE hProcess = NULL; //打开进程句柄 hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,dwID); if(hProcess != NULL) { //终止进程 TerminateProcess(hProcess,0); ::CloseHandle(hProcess); } }
//获取进程快照 void GetProcessInfo() { SHFILEINFO shSmall; int nIndex; CString str; //声明进程信息变量 PROCESSENTRY32 ProcessInfo; //获取系统中的所有进程信息 HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(SnapShot != NULL) { m_ListCtrl.DeleteAllItems(); //设置ProcessInfo的大小 ProcessInfo.dwSize = sizeof(PROCESSENTRY32); //返回系统中第一个进程的信息 BOOL Status = Process32First(SnapShot,&ProcessInfo); //进程计数 int m_nProcess = 0; while(Status) { m_nProcess++; ZeroMemory(&shSmall,sizeof(shSmall)); //获取进程文件的信息 SHGetFileInfo(ProcessInfo.szExeFile,0,&shSmall, sizeof(shSmall),SHGFI_ICON|SHGFI_SMALLICON); //在列表控件中添加映像名称 nIndex = m_ListCtrl.InsertItem(m_nProcess,ProcessInfo.szExeFile); //在列表控件中添加进程PID str.Format("%08X",ProcessInfo.th32ProcessID); m_ListCtrl.SetItemText(nIndex,1,str); //在列表控件中添加进程的父进程PID str.Format("%08X",ProcessInfo.th32ParentProcessID); m_ListCtrl.SetItemText(nIndex,2,str); //获取进程路径 str = GetProcessPath(ProcessInfo.th32ProcessID); m_ListCtrl.SetItemText(nIndex,3,str); //获取下一个进程信息 Status = Process32Next(SnapShot,&ProcessInfo); } } else MessageBox("获取进程信息失败!"); } //获取模块快照 void GetProcessModule(DWORD dwID) { MODULEENTRY32 me32; int nIndex; CString str;
// 在使用这个结构之前,先设置它的大小 me32.dwSize = sizeof(me32);
// 给进程内所有模块拍一个快照 HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwID); if(hModuleSnap == INVALID_HANDLE_VALUE) { //建立快照失败 MessageBox("获取模块信息失败!", "提示", MB_OK|MB_ICONWARNING); return; }
// 遍历模块快照,轮流显示每个模块的信息 BOOL bMore = Module32First(hModuleSnap, &me32); int m_nModule = 0; while(bMore) { m_nModule++; nIndex = m_listmod.InsertItem(m_nModule, me32.szExePath);//模块路径 str.Format("%u", me32.modBaseSize);//模块大小 m_listmod.SetItemText(nIndex,1,str); bMore = Module32Next(hModuleSnap, &me32); } // 不要忘记清除掉snapshot对象 CloseHandle(hModuleSnap); }
// // FindProcess // 这个函数唯一的参数是你指定的进程名,如:你的目标进程 // 是 "Notepad.exe",返回值是该进程的ID,失败返回0 //
DWORD FindProcess(char *strProcessName) { DWORD aProcesses[1024], cbNeeded, cbMNeeded; HMODULE hMods[1024]; HANDLE hProcess; char szProcessName[MAX_PATH];
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 0; for(int i=0; i< (int) (cbNeeded / sizeof(DWORD)); i++) { //_tprintf(_T("%d "), aProcesses[i]); hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]); EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbMNeeded); GetModuleFileNameEx( hProcess, hMods[0], szProcessName,sizeof(szProcessName));
if(strstr(szProcessName, strProcessName)) { //_tprintf(_T("%s;"), szProcessName); return(aProcesses[i]); } //_tprintf(_T(" ")); } return 0; }
// // KillProcess // 此函数中用上面的 FindProcess 函数获得你的目标进程的ID // 用WIN API OpenPorcess 获得此进程的句柄,再以TerminateProcess // 强制结束这个进程 //