“星魔”回忆录【2】

3.右键监听的及停止监听的功能

void CClient_Dlg::OnListen()

{

// TODO: Add your command handler code here

CString cs;

if(IsListen==TRUE)        //是否正在监听的标志位

{

   if(GlobalSock)

   {

    closesocket(GlobalSock);    //关闭监听套接字

    GlobalSock=0;

    SetWindowText(“星魔v1.0″);    //重新设置对话框标题

    IsListen=FALSE;       //重置标志位

    return;

   }

}

HANDLE hd=CreateThread(NULL,0,InitConnect,(LPVOID)this,0,NULL); //监听线程

CloseHandle(hd);

GetWindowText(cs);

cs+=”-等待主机上线….”;

SetWindowText(cs);

IsListen=TRUE;           //监听标志位

}

监听线程的代码比较长。不贴出来了。看程序中的吧。

4.防止用户铵下键盘的ESC键和ENTER键退出程序,重载PreTranslateMessage函数

BOOL CClient_Dlg::PreTranslateMessage(MSG* pMsg)

{

// TODO: Add your specialized code here and/or call the base class

//防止用户按下回车和ESC后退出

if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)

   return FALSE;

if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE)

   return FALSE;

  


return CDialog::PreTranslateMessage(pMsg);

}

5.右键菜单,重载CListCtrl的OnRclickServerlist函数

void CClient_Dlg::OnRclickServerlist(NMHDR* pNMHDR, LRESULT* pResult)

{

// TODO: Add your control notification handler code here   

CMenu menu;

VERIFY(menu.LoadMenu(IDR_MENU));    //加载菜单


CPoint point;

GetCursorPos(&point);

CMenu* pPopup = menu.GetSubMenu(0);

ASSERT(pPopup != NULL);

CWnd* pWndPopupOwner = this;


if(m_ServerList.GetSelectedCount()<=0)   //如果没有选中CListCtrl中的一项

{

    pPopup->EnableMenuItem(ID_CONTROL,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); //把“控制”变灰

    pPopup->EnableMenuItem(ID_DISCONNECT,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); //“断开变灰”

    pPopup->EnableMenuItem(ID_SET_REMARK_INFO,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); //“备注”变灰

    pPopup->EnableMenuItem(ID_SET_SERVER_PWD,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); //”设置服务端密码”变灰

    pPopup->EnableMenuItem(ID_UNLOADSERVER,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);   //“卸载服务端”变灰

}

if(IsListen==TRUE)     //如果正在监听状态

{

    pPopup->RemoveMenu(ID_LISTEN,MF_BYCOMMAND);    //删掉菜单项“监听”

    pPopup->InsertMenu(ID_CREATESERVER,MF_BYCOMMAND|MF_STRING,ID_LISTEN,”停止监听”); //添加菜单项”停止监听”,紧挨着”创建服务端菜单”

    DrawMenuBar();   //菜单重绘

    pPopup->EnableMenuItem(ID_LISTEN,MF_BYCOMMAND | MF_ENABLED ); //把”停止监听”变可用

}


while (pWndPopupOwner->GetStyle() & WS_CHILD)

   pWndPopupOwner = pWndPopupOwner->GetParent();


pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,

    pWndPopupOwner);    //弹出菜单

*pResult = 0;

}

OK.今天到这。。明天接着写菜单项各个功能。。

“星魔”回忆录【1】

想写一个做“星魔”的整个过程。。算是回忆录吧。呵呵。。把用到的细小技术和点点滴滴全都写出来。。也许技术含量不算高。。希望对一些人有用吧。。

一.界面设计

点击右键弹出菜单。。没有菜单栏。。觉得这样比较简洁。。

建立MFC框架的对话框。。设计上图这样。。

我命名工程名为“Client_”,在CClient_App类中的InitInstance()方法中完成几个任务:

类成员函数及变量

void InitCreateFile(CString cs_filename,int cs_resource,CString ResourceType);



HMODULE hmdl;

1.只允许一个实例运行。

HANDLE hdMutex=CreateMutex(NULL,TRUE,CLIENTMUTEXNAME);

if(NULL!=hdMutex)

{

   if(GetLastError()==ERROR_ALREADY_EXISTS)

   {

    AfxMessageBox(“已有一个程序实例在运行”);

    return TRUE;

   }

}

2.释放临时文件

释放皮肤需要的DLL文件及启动画面的swf文件

3.皮肤设置

调用皮肤所需要的函数

在ExitInstance() 中释放动态链接库及删除临时文件

至此,CClient_App类中的工作即完成。

二.主对话框的操作

下面开始CClient_Dlg对话框中的工作

1.点监听的时候。开启一个线程用于监听服务端的连接。。在InitDialog重载函数中开启一个心跳线程。。每隔一定时间遍历CListCtrl并发送数据包。来判断服务端是否在线。如果不在线则把它从CListCtrl中删除

2.在初始化对话框的时候同时进行socket初始化

WORD ver=MAKEWORD(2,2);      //初始化

WSAStartup(ver,&wsadata);

任务栏的气泡提示

nf.cbSize = (DWORD)sizeof(NOTIFYICONDATA);

nf.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP|NIF_INFO ;

nf.dwInfoFlags=NIIF_INFO;

nf.hWnd=this->m_hWnd;

nf.uID=IDR_MAINFRAME;

nf.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));

strcpy(nf.szTip,”星魔远程控制……..”);

strcpy(nf.szInfoTitle,”提示!”);

strcpy(nf.szInfo,”星魔远程控制已启动!”);

nf.uCallbackMessage=WM_SHOWTASK;

Shell_NotifyIcon(NIM_ADD,&nf);

初始化CListCtrl控件的CImageList.以及设置CListCtrl的风格

m_ImageList.Create(18, 18, ILC_COLOR32, 10, 0);

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_COMPUTER));

CRect rect;

::GetWindowRect(m_ServerList.m_hWnd,&rect);

DWORD dwidth;

dwidth=rect.Width()/SERVERLISTCOLUMN;

m_ServerList.SetExtendedStyle(m_ServerList.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

m_ServerList.SetImageList(&m_ImageList,LVSIL_SMALL);


m_ServerList.InsertColumn(1,”所在地区”,LVCFMT_CENTER,dwidth);

m_ServerList.InsertColumn(2,”计算机名称”,LVCFMT_CENTER,dwidth);

m_ServerList.InsertColumn(3,”IP地址”,LVCFMT_CENTER,dwidth);

m_ServerList.InsertColumn(4,”内存”,LVCFMT_CENTER,dwidth);

m_ServerList.InsertColumn(5,”当前用户名”,LVCFMT_CENTER,dwidth);

m_ServerList.InsertColumn(6,”备注信息”,LVCFMT_CENTER,dwidth);

更改对话框的风格

DWORD style=WS_THICKFRAME|WS_MAXIMIZEBOX|WS_MINIMIZEBOX;

ModifyStyle(0,style);

让CListCtrl随窗口的大小的变化而改变,以使其适应窗口

MoveCtrl();

void CClient_Dlg::MoveCtrl()

{

if(m_ServerList.m_hWnd!=0)

{

   //首先移动CListCtrl,与窗口位置和大小保持一致

   //CRect Btrect;

   //((CButton*)GetDlgItem(IDOK))->GetClientRect(&Btrect);

  

   CRect rect;        //父窗口的位置

   GetClientRect(&rect);

//   m_ServerList.SetWindowPos(&wndTop,rect.left,rect.right,rect.Width(),rect.Height(),);

   rect.left=rect.left+5;

   rect.bottom=rect.bottom-5;

   rect.top=rect.top;

   rect.right=rect.right-5;

  

  

   m_ServerList.MoveWindow(&rect);

   CRect crect;

   ::GetWindowRect(m_ServerList.m_hWnd,&crect);

   DWORD dwidth;

   dwidth=crect.Width()/SERVERLISTCOLUMN;

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

    m_ServerList.SetColumnWidth(i,dwidth);

}

}

开启心跳线程

HANDLE hd=CreateThread(NULL,0,KeepLive,this,0,NULL);

CloseHandle(hd);

心跳线程的代码部分

DWORD WINAPI CClient_Dlg::KeepLive(LPVOID lparm)

{

CClient_Dlg* ccd=(CClient_Dlg*)lparm;

CListCtrl* clc=&ccd->m_ServerList;

SOCKET sock;

int ServerNum=0;


while (1)

{

   ServerNum=clc->GetItemCount();

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

   {

    sock=(SOCKET)clc->GetItemData(i);

    if(SOCKET_ERROR==send(sock,”test”,sizeof(“test”),0))

    {

     clc->DeleteItem(i);

    }

  

   }

   Sleep(20000);

}

return 0;

}

休息。。。

终于整完了。。完工了。。完工了。。哦耶。。。。克服了很多困难。。困难是暂时的。。总有办法可以解决。。。。休息。。休息。。休息几天。。。

C++ int,char,string,CString类型转换(整理总结)

C++ int,char,string,CString类型转换(整理总结)

2007-11-09 12:34:38 原文地址: http://blog.sina.com.cn/s/blog_4c22ff8d01000ati.html [查看原文]

#include <string> //使用C++标准库的string类时

using namespace std; //同上

#include <sstream>  

#include <iostream>

#include <stdlib.h>    //要将string类和int类型直接转换最好有这些包含,

                       //因为自己写一个转换函数比较方便,函数定义参考如下

string getstring ( const int n )

{

    std::stringstream newstr;

    newstr<<n;

    return newstr.str();

}

////////////////// 以下转载自http://successfulfortune.com/icode/?p=4                         

string 转 CString

CString.format(”%s”, string.c_str());

char 转 CString

CString.format(”%s”, char*);

char 转 string

string s(char *);

string 转 char *

char *p = string.c_str();

CString 转 string

string s(CString.GetBuffer());

1,string -> CString

CString.format(”%s”, string.c_str());

用c_str()确实比data()要好.

2,char -> string

string s(char *);

只能初始化,在不是初始化的地方最好还是用assign().

3,CString -> string

string s(CString.GetBuffer());

GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.

《C++标准函数库》中说的

有三个函数可以将字符串的内容转换为字符数组和C

QQ截图截取右键菜单。。

有时候要截取图片,可能也要涉及到右键菜单,截取右键菜单可是非常的不容易,因为你点击右键,然后再点截图软件,右键菜单就消失了,可以说是右键菜单是瞬而即逝,没办法迅速捕捉到的。一般都是采用Ctrl+Print键全屏截图,然后再在Photoshop软件里处理,不过这样相对麻烦。


截取右键菜单更简单的日子到来了,笔者发现,原来QQ截图是拥有截取右键菜单的功能,不过很多人都甚少听闻。比起一些专业截图软件,也无法截取到右键菜单,而QQ截图竟然能做到,是不是觉得有点太不可思议。下面给大家说说QQ截图如何截取右键菜单。


方法其实很简单:


1:打开任意一个QQ聊天窗口


2:按住shift+ctrl+Alt+A四个键然后点击右键


3:松开shift(其它键不要松开)看看,现在是不是就是QQ截图了,呵呵,大功告成。

美化您的程序――SkinMagic使用方法完美总结[转载]

2.0版

把corona.smf,SkinMagicLibMD6.lib,SkinMagicLib.h考入程序文件夹中.

在stdafx.h中添加代码

#include “SkinMagicLib.h”

//#pragma comment(lib, “SkinMagicLibMD6Trial.lib”)

#pragma comment(lib, “SkinMagicLibMD6.lib”)

/* 当在Project/Setting/General中选择”Use MFC in a Static Library”时,

   需要以下两条语句:

*/

#pragma comment(linker, “/FORCE:MULTIPLE”)

#pragma comment(linker, “/OPT:NOREF”)

在主文件添加头文件

#define COMPILE_MULTIMON_STUBS

#include “multimon.h”



在BOOL CMDIDemoApp::InitInstance()开头添加

VERIFY( 1 == InitSkinMagicLib( AfxGetInstanceHandle(), _T(“Demo”) ,

       NULL,

       NULL ) );

VERIFY( 1 == LoadSkinFile( _T(“corona.smf”) ) );

在尾部 pMainFrame->ShowWindow(m_nCmdShow);

pMainFrame->UpdateWindow();

之前添加

VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , _T(“MainFrame”) ));

SetControlTooltip( pMainFrame->m_wndToolBar.m_hWnd , _T(“ToolBar”) );

VERIFY( 1 == SetDialogSkin( _T(“Dialog”) ) );

之后就编译成功了,继续为子窗口重载WM_CREATE或WM_INITDIALOG

在其中添加代码SetWindowSkin( m_hWnd , _T(“MainFrame”) );

2.2版

1、下载SkinMagic Toolkit,复制SkinMagicTrial.dll、SkinMagicTrial.lib、SkinMagicLib.h以及皮肤文件corona.smf至项目的目录下。(这样比较简单J,可以在这下载。)

2、在stdafx.h中加入头文件和库的引用,如下:

#i nclude “SkinMagicLib.h”

#pragma comment(lib, “SkinMagicTrial.lib”)



l       使用SkinMagic

1、 初始化SkinMagic库:

int __stdcall InitSkinMagicLib( HINSTANCE hInstance,

                                                                    LPCTSTR lpApplication ,

                                                                    LPCTSTR lpReserved1,

                                                                   LPCTSTR lpReserved2 );

在 CxxxApp::InitInstance()中加入初始化SkinMagic库的代码:

       VERIFY( 1 == InitSkinMagicLib(AfxGetInstanceHandle(), NULL, NULL, NULL));

2、调入皮肤文件:

        皮肤的调用有两种方法,一是直接从皮肤文件中调用,另一种方法是从资源文件中调用,分别说明如下:

1) 从皮肤文件中调用皮肤:

int __stdcall LoadSkinFile( LPCTSTR lpSkinFile );

2)从资源文件中调用皮肤:

int __stdcall LoadSkinFromResource(HMODULE hModule,

                     LPCTSTR lpSkinName ,

LPCTSTR lpType);

现在CxxxApp::InitInstance()中的代码如下:

BOOL CxxxApp::InitInstance()

{

         VERIFY( 1 == InitSkinMagicLib(AfxGetInstanceHandle(), NULL, NULL, NULL));

         VERIFY( 1 == LoadSkinFile(“corona.smf”));

         AfxEnableControlContainer();

    //…..下略

}

3、将皮肤应用到程序上

       int __stdcall SetWindowSkin( HWND hWnd , LPCTSTR lpSkinName );

 int __stdcall SetDialogSkin( LPCTSTR szSkinName );

1)对话框程序代码位置:

BOOL CxxxApp::InitInstance()

{

         //…上略

         m_pMainWnd = &dlg;

         VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , “MainFrame” ));

    VERIFY( 1 == SetDialogSkin( “Dialog” ) );

         int nResponse = dlg.DoModal();

    //…下略

}

2)文档视图程序代码的位置

BOOL CxxxApp::InitInstance()

{

         //…上略

         m_pMainWnd->ShowWindow(SW_SHOW);

         m_pMainWnd->UpdateWindow();

         VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , “MainFrame” ));

    VERIFY( 1 == SetDialogSkin( “Dialog” ) );

         return TRUE;

}

4、释放SkinMagic资源

void __stdcall ExitSkinMagicLib();

重载应用程序的ExitInstance()函数,添加如下代码:

int CxxxApp::ExitInstance()

{

                  ExitSkinMagicLib();

         return CWinApp::ExitInstance();

}

WM_CREATE 和 WM_INITDIALOG 什么时候发送的?

小结:

WM_CREATE是所有窗口都能响应的消息,表明本窗口已经创建完毕.可以安全的使用这个窗口了,例如在它上面画控件等等.这个状态肯定是在调用ShowWindows()显示窗口之前.

WM_WM_INITDIALOG是对话框才能收到的消息,表明对话框及其所有子控件都创建完毕了,这个状态肯定是调用显示对话框的函数之前.所以可以在WM_WM_INITDIALOG对控件进行一些修改等.

——-

nvneibaba_069 – 初级水手长 七级

不要被MFC干扰了,MFC封装了太多的东西,心里想着API的执行顺序就行了。

所有窗口都是在注册窗口类之后调用CreateWindowEx来创建的,创建成功之后(HWND有效但CreateWindowEx尚未返回)系统自动发送WM_CREATE消息,所以你的OnCreate将被执行,在这里窗口已经创建成功了,你可以安全地创建各种子窗口。

——-

——-

http://www.cppblog.com/pwqonline/archive/2008/12/04/67806.html

WM_CREATE消息响应函数和WM_INITDIALOG消息响应函数之区别

          在响应WM_CREATE消息响应函数的时候,对话框及子控件还未创建完成,亦是说只是通知系统说要开始创建窗口啦,这个消息响应完之后,对话框和子控件才开始创建。因此在此消息响应函数中无法对控件进行修改和初始化。


          而WM_INITDIALOG消息响应函数是在程序运行时,当其对话框和子控件全部创建完毕,将要显示内容的时候发送的消息。因此可以在WM_INITDIALOG消息响应函数中添加对编辑框控件的初始化和修改。



——-

WM_CREATE消息用来产生子窗口控件,WM_CREATE是谁发出的,什么意思??

当然是windows操作系统发出,所有消息都是由操作系统发出给程序的,分成进队消息,和不进队

消息,wm_create不仅仅指子窗口产生,所有窗口在操作系统内部产生时,windows都会发出这个消息

——–

应用程序中处理消息的顺序(转)

MFC应用程序中处理消息的顺序

1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc

2.AfxCallWndProc() 该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,

                    然后调用WindowProc()函数

3.WindowProc()      该函数负责发送消息到OnWndMsg()函数,如果未被处理,则调用DefWindowProc()函数

4.OnWndMsg()        该函数的功能首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息

                    响应函数,对于WM_NOTIFY消息

                    调用OnNotify()消息响应函数。任何被遗漏的消息将是一个窗口消息。OnWndMsg()函数搜

                    索类的消息映像,以找到一个

                    能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则

                    把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数

5.OnCommand()       该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明

                    该消息不是控件通知),如果它是,OnCommand()函数会试图将消息映射到制造通知的控件;

                    如果他不是一个控件通知(或者如果控件拒绝映射的消息)OnCommand()就会调用OnCmdMsg()函数

6.OnCmdMsg()        根据接收消息的类,OnCmdMsg()函数将在一个称为命令传递(Command Routing)的过程中潜在的

                    传递命令消息和控件通知。

                    例如:如果拥有该窗口的类是一个框架类,则命令和通知消息也被传递到视图和文档类,并为该

                    类寻找一个消息处理函数

MFC应用程序创建窗口的过程

1.PreCreateWindow()   该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数

                      (可以设置窗口风格等等)

2.PreSubclassWindow() 这也是一个重载函数,允许首先子分类一个窗口

3.OnGetMinMaxInfo()   该函数为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者

                      最小尺寸

4.OnNcCreate()        该函数也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区

                      即将被创建

5.OnNcCalcSize()      该函数也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小

6.OnCreate()          该函数也是一个消息响应函数,响应WM_CREATE消息,发送消息告诉一个窗口已经被创建

7.OnSize()            该函数也是一个消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经

                      发生变化

8.OnMove()            消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动

9.OnChildNotify()     该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被

                      创建

MFC应用程序关闭窗口的顺序(非模态窗口)

1.OnClose()       消息响应函数,响应窗口的WM_CLOSE消息,当关闭按钮被单击的时候发送此消息

2.OnDestroy()     消息响应函数,响应窗口的WM_DESTROY消息,当一个窗口将被销毁时,发送此消息

3.OnNcDestroy()   消息响应函数,响应窗口的WM_NCDESTROY消息,当一个窗口被销毁后发送此消息

4.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作,被CWnd调用



MFC应用程序中打开模式对话框的函数调用顺序

1.DoModal()             重载函数,重载DoModal()成员函数

2.PreSubclassWindow()   重载函数,允许首先子分类一个窗口

3.OnCreate()            消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建

4.OnSize()              消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化

5.OnMove()              消息响应函数,响应WM_MOVE消息,发送此消息,以告诉窗口正在移动

6.OnSetFont()           消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体

7.OnInitDialog()        消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,

                        或者是创建新控件

8.OnShowWindow()        消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用

9.OnCtlColor()          消息响应函数,响应WM_CTLCOLOR消息,被父窗口发送已改变对话框或对话框上面控件

                        的颜色

10. OnChildNotify()     重载函数,作为WM_CTLCOLOR消息的结果发送

MFC应用程序中关闭模式对话框的顺序

1.OnClose()        消息响应函数,响应WM_CLOSE消息,当”关闭”按钮被单击的时候,该函数被调用

2.OnKillFocus()    消息响应函数,响应WM_KILLFOCUS消息,当一个窗口即将失去键盘输入焦点以前被发送

3.OnDestroy()      消息响应函数,响应WM_DESTROY消息,当一个窗口即将被销毁时,被发送

4.OnNcDestroy()    消息响应函数,响应WM_NCDESTROY消息,当一个窗口被销毁以后被发送

5.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用



打开无模式对话框的顺序

1.PreSubclassWindow()    重载函数,允许用户首先子分类一个窗口

2.OnCreate()             消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建

3.OnSize()               消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化

4.OnMove()               消息响应函数,响应WM_MOVE消息,发送此消息以告诉窗口正在移动

5.OnSetFont()            消息响应函数,响应WM_SETFONT消息,发送此消息以允许改变对话框中控件的字体



以上这些的执行都是按给定的顺序执行!

只有清楚的了解应用程序的执行顺序,才能在编写代码的时候知道,在什么时候应该执行什么,以及在什么地方该处理什么!

这只是本人总结的一点小小的经验,希望能对MFC的初学者有所帮助!