Archive for 3月 2014

在windows和linux使用wxWidgets编写程序

按照上一篇文章http://www.zoudaokou.com/index.php/archives/658安装完wxWidgets后,就可以开始wxWidgets编程之旅了。

在windows下,创建一个VC工程,然后配置工程属性,加入wx的include路径,需要注意的是,在编译时会报setup.h找不到,它在include\msvc\wx目录下,将其复制到include\wx下再编译。然后再加入wx的lib路径及所需要的lib文件wxmsw30u_html.lib wxmsw30u_core.lib wxbase30u.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregexu.lib wxexpat.lib即可。

在linux下,使用make install会将include和lib都安装到usr/local目录中,在写makefile文件时需要指定它们的路径和名称,而在编译wx时会生成wx-config文件,这个文件可以用来自动指定include和lib的位置以及一些编译选项,使用wx-config –libs或wx-config –cxxflags即可。

新建一个minimal.cpp文件,内容如下:

// wxWidgets "Hello world" Program

// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

class MyApp: public wxApp
{
public:
    virtual bool OnInit();
};

class MyFrame: public wxFrame
{
public:
    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
private:
    void OnHello(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);

    wxDECLARE_EVENT_TABLE();
};

enum
{
    ID_Hello = 1
};

wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(ID_Hello,   MyFrame::OnHello)
    EVT_MENU(wxID_EXIT,  MyFrame::OnExit)
    EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
wxEND_EVENT_TABLE()

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame( "Hello World", wxPoint(50, 50), wxSize(450, 340) );
    frame->Show( true );
    return true;
}

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : wxFrame(NULL, wxID_ANY, title, pos, size)
{
    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
                     "Help string shown in status bar for this menu item");
    menuFile->AppendSeparator();
    menuFile->Append(wxID_EXIT);
    wxMenu *menuHelp = new wxMenu;
    menuHelp->Append(wxID_ABOUT);
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append( menuFile, "&File" );
    menuBar->Append( menuHelp, "&Help" );
    SetMenuBar( menuBar );
    CreateStatusBar();
    SetStatusText( "Welcome to wxWidgets!" );
}

void MyFrame::OnExit(wxCommandEvent& event)
{
    Close( true );
}

void MyFrame::OnAbout(wxCommandEvent& event)
{
    wxMessageBox( "This is a wxWidgets' Hello world sample",
                  "About Hello World", wxOK | wxICON_INFORMATION );
}

void MyFrame::OnHello(wxCommandEvent& event)
{
    wxLogMessage("Hello world from wxWidgets!");
}

Continue reading ‘在windows和linux使用wxWidgets编写程序’ »

linux编译wxWidgets

windows编译wxWidgets没什么好说的,解压wxWidgets后,找到build\msw下面的.dsw或.sln文件,打开编译即可,它有四种编译模式,Debug和Release是编译成静态库调用的,Debug dll和Release dll是编译成动态库的。

而linux编译wxWidgets是需要gtk库,若系统中未安装gtk则需要手动安装,ubuntu可以直接使用sudo apt-get install libgtk-3-dev来安装,大约17M左右,Suse可以使用yast来安装。在使用./configure命令时报找不到gtk则要先安装gtk。

wxWidgets库是使用bz2格式压缩的,先使用

bzip2 -d wxWidgets-3.0.0.tar.bz2

解压成wxWidgets-3.0.0.tar文件,然后使用

tar -xvf wxWidgets-3.0.0.tar

解压到wxWidgets-3.0.0目录,然后进入到该目录,执行./configure

cd wxWidgets-3.0.0
./configure

配置约两分钟左右,完成后,进行编译

make

未指定安装目录,则默认安装到系统/usr/目录中,有些系统需要root权限,否则执行make install时会报权限不够,所以先使用su切换成root用户

su
make install
ldconfig

这样wxWidgets就安装好了,可以使用下面的命令查询wxWidgets的配置

wx-config --libs
wx-config --cxxflags

上面这两条命令是查看wxWidgets的lib路径及需要链接的动态库名称,以及预编译处理器的定义。

立体人行横道

这就是传说中的中国人民大学高端大气上档次的立体人行横道。据说开车的人会因为看到是立体的障碍物而减速。从而保证过往行人的安全……

1

枚举进程调用Process32First失败返回24

在进行系统进程枚举时,调用了windows的API Process32First,结果调用失败,使用GetLastError返回错误号为24,这是因为没有初始化它的LPPROCESSENTRY32结构体dwSize值。

在MSDN对Process32First函数的介绍Remarks中提到,必须要为PROCESSENTRY32的dwSize赋值:

The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure. 

枚举进程代码如下:

int CMonitorModule::EnumProcess()
{
	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
	{
		DWORD error = GetLastError();
		printf("Cannot get system process snapshot (%d)\n", error);
		return -1;
	}

	PROCESSENTRY32 pe32 = {0};
	pe32.dwSize = sizeof(PROCESSENTRY32); //必须填充结构体的大小值
	if(!Process32First(hProcessSnap, &pe32))
	{
		DWORD error = GetLastError();
		printf("Process32First failed (%d)\n",error );
		CloseHandle(hProcessSnap);
		return -1;
	}
	do
	{
		printf(Process name :%s\n", pe32.szExeFile);
	} while(Process32Next(hProcessSnap, &pe32));

	CloseHandle( hProcessSnap );
	return 0;
}

调用WinINet的HttpSendRequest返回12002超时

在使得WinINet进行文件下载时,发现前几次都能够正常下载,但在某一次操作以后,调用HttpSendRequest一直失败,返回错误号是12002,查询MSDN,对这个错误的描述是The request has timed out.

经过排查发现,工作到某一次时,没有关闭request句柄,导致后续调用HttpSendRequest一直失败,按照顺序关闭request句柄问题解决。

if (hReq)
{
	InternetCloseHandle(hReq);
}
if (hConnect)
{
	InternetCloseHandle(hConnect);
}
if (hOpen)
{
	InternetCloseHandle(hOpen);
}

任意进制转换工具

任意进制自动转换工具是一个多种进制间自动转换的实用工具,只要在工具中输入其中一种进制数,即可进行2进制、3进制,一直到36进制进制之间全自动相互转换。

软件界面如下图

1
Continue reading ‘任意进制转换工具’ »

Base64加密解密工具

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。

Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME,在XML中存储复杂数据。

为了方便的进行Base64加密解密,我花了一点时间制作了这个工具,使用非常简单,界面如下图:

1
Continue reading ‘Base64加密解密工具’ »

春风走十里,独留你

春风走了十里,独留你在这里,与我相伴,携手一起走这阳光明媚的夏日。

1
Continue reading ‘春风走十里,独留你’ »