Dec 4

对于有vb或者c#开发经验的程序员来说,窗体应用程序不过是拖拖控件了事,下面介绍一种比较古老的技术,也就所谓win32开发,使用windows函数库来创建windows应用程序

 

#define WIN32_LEAN_AND_MEAN
#define WindowsName "win1"

#include <Windows.h>
#include <WindowsX.h>

LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch(msg)
	{
		//创建
		case WM_CREATE:
			return 0;
			break;
		//重绘
		case WM_PAINT:
			hdc=BeginPaint(hwnd,&ps);
			return 0;
			break;
		//销毁
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			break;
	}

	return DefWindowProc(hwnd,msg,wparam,lparam);
}


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpcmdline,int ncmdshow)
{
	//窗体类
	WNDCLASSEX winclass;
	HWND hwnd;
	MSG msg;

	winclass.cbSize=sizeof(WNDCLASSEX);
	winclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
	winclass.lpfnWndProc=WindowProc;
	winclass.cbClsExtra=0;
	winclass.cbWndExtra=0;
	winclass.hInstance=hInstance;
	winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
	winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	winclass.lpszMenuName=NULL;
	winclass.lpszClassName=WindowsName;
	winclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

	//注册窗体
	if(!RegisterClassEx(&winclass))
	{
		return 0;
	}

	//创建
	if(!(hwnd=CreateWindowEx(NULL,
		WindowsName,
		"我的第一个窗体",
		WS_OVERLAPPEDWINDOW|WS_VISIBLE,
		0,
		0,
		400,
		400,
		NULL,
		NULL,
		hInstance,
		NULL
		)))
	{
		return 0;
	}



	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);

		DispatchMessage(&msg);
	}

	//while(true)
	//{
	//	if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE) && PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
	//	{
	//		MessageBox(NULL,"test","标题",NULL);
	//		if(msg.message==WM_QUIT)
	//		{
	//			break;
	//		}
	//		TranslateMessage(&msg);
	//		DispatchMessage(&msg);
	//	}
	//}

	return msg.wParam;
}

这段代码可以在vs2010中的c++项目中编译成功,有空会写出相应的文章

短短80多行代码足以创建一个黑色背景的窗体

涵盖了:

1、注册windows类

2、创建窗体

3、事件处理

4、主事件循环

 

我尝试每句话都解释一下

 

#define WIN32_LEAN_AND_MEAN

 

这句话的意思是不想要使用MFC来开发,具体什么是MFC,请另百度搜索

 

#define WindowsName "win1"

#include <Windows.h>
#include <WindowsX.h>

 

第一句为宏定义,把WindowsName定义为"win1"的别名,用来给窗体起名字的

第二和第三句分别导入两个函数库,用来进行windows开发的最基本函数库

 

LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch(msg)
	{
		//创建
		case WM_CREATE:
			return 0;
			break;
		//重绘
		case WM_PAINT:
			hdc=BeginPaint(hwnd,&ps);
			return 0;
			break;
		//销毁
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			break;
	}

	return DefWindowProc(hwnd,msg,wparam,lparam);
}

 

这是回调函数。

对窗体产生的事件进行处理

比如有

WM_CREATE创建,WM_PAINT绘制,WM_DESTROY销毁

而触发这三种事件的条件是传入了怎样的消息msg

当msg符合创建条件时,就会进入switch条件分支的WM_CREATE中(这简直“太容易理解了”)

总之msg的赋值你并不需要关注,这是系统替我们赋值的

 

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpcmdline,int ncmdshow)

 

这句话是win32程序的标准main函数,也就所谓大门,main方法不必过多赘述,跟其他语言一个意思

只不过是多了一点点其他的东西,比如这个int WINAPI WinMain的写法就是十分奇葩,其实就是int WinMain中间多了一个WINAPI

这个WINAPI规定了函数参数的入栈方式是最右边先入栈,这不需要过多的关注,在以后的研究中会搞明白入栈方式对编程的影响。

 

//窗体类
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;

 

第一句话注册了一个窗体类,由于win32编程是用c语言开发的,说是类,但没有class关键字,经过一步步F12追踪源代码,我发现WNDCLASSEX是一个结构体struct, 用来规定窗体长什么样子

HWND hwnd是一个窗体句柄,也就所谓窗体的一个身份标识,再简单的理解,就是身份证

MSG msg是消息,用来确定是执行绘制窗体还是创建窗体,或者是销毁窗体

 

        winclass.cbSize=sizeof(WNDCLASSEX);
	winclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
	winclass.lpfnWndProc=WindowProc;
	winclass.cbClsExtra=0;
	winclass.cbWndExtra=0;
	winclass.hInstance=hInstance;
	winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
	winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	winclass.lpszMenuName=NULL;
	winclass.lpszClassName=WindowsName;
	winclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

 

规定了很多,如窗体的样式,光标,鼠标,背景颜色等等,其中有两句很重要

winclass.lpfnWndProc=WindowProc;

winclass.lpszClassName=WindowsName;

第一句话规定了本窗体的回调函数是谁,第二句话规定了本窗体的名字叫什么

 

	//注册窗体
	if(!RegisterClassEx(&winclass))
	{
		return 0;
	}

 

用RegisterClassEx来注册窗体,只有注册过的窗体才能使用,注册失败就让WinMain主函数返回0

 

	//创建
	if(!(hwnd=CreateWindowEx(NULL,
		WindowsName,
		"我的第一个窗体",
		WS_OVERLAPPEDWINDOW|WS_VISIBLE,
		0,
		0,
		400,
		400,
		NULL,
		NULL,
		hInstance,
		NULL
		)))
	{
		return 0;
	}

创建窗体,规定了大小之类的琐事

 

	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);

		DispatchMessage(&msg);
	}

消息循环,用来转发消息,确定你是要做什么事,比如WM_CREATE创建,WM_PAINT绘制,WM_DESTROY销毁

而且这还是个while循环,不停的在判断是否有事件发生

 

----------备注------------

简单先写这些,本文未完成,对关键函数以及变量的解释不够,在后面的研究深入中慢慢加入

 

 

 

 

 

 

 

 

Nov 30

写在开始

过去2年了

从编程的菜鸟一天天长大,获得了巨大的编程经验

现在作为很多学生的老师

需要经常自我充电用以补充知识

才不致被越来越聪明的学生问跨

虽然一时半会儿还不会被问倒罢

有个地方当作自己学习的备忘录

就在这里

Mar 26

修改注册表

regedit.exe

 

开始——regedit.exe
HKEY_CLASSES_ROOT\Applications\javaw.exe\shell\open\command
默认(左击)——右键(修改)——"D:\java\jre\bin\javaw.exe" -jar "%1" %*

HKEY_CLASSES_ROOT\jar_auto_file\shell\open\command
默认(左击)——右键(修改)——"D:\java\jre\bin\javaw.exe" -jar "%1" %*
Nov 7

开始自学php,代码是自己从网上找的,写在这里作为笔记翻看。

我有SSH整合的经验,也有基础的jdbc知识,学php照猫画虎吧。

查询功能:

 

<?php
//设置页面编码格式
header ( "content-Type: text/html; charset=GBK" );
//生成连接对象$conn,三个参数分别是数据库的用户名,密码,以及sid
$conn = oci_connect ( 'testphp', '123', 'ORACLE11' );
//sql语句
$sql = "select * from userinfo";
//这句话相当于jdbc的preparestatement对象
$statement = oci_parse ( $conn, $sql );
//执行,返回值类型为boolean
if (oci_execute ( $statement )) {
//OCI_BOTH是数字和列名同时索引,如$row[1]和$row['username']的意义是相同的
	while ( ($row = oci_fetch_array ( $statement, OCI_BOTH )) ) {
		echo $row ['USERNAME'] . " " . $row ['PASSWORD'] . "<br>";
		
	}
}
//释放以及关闭资源
oci_free_statement ( $statement );
oci_close ( $conn );
?> 

插入功能:

 

<?php
header ( "content-Type: text/html; charset=GBK" );
?>
<script type="text/javascript">
function validate(){
	var username=document.getElementById("username").value;
	var password=document.getElementById("password").value;
	var pwd=document.getElementById("pwd").value;

	
		document.getElementById("form1").submit();
	
	
	
}
</script>
<form id="form1" action="insertUserinfo.php" method="post">
<table>
	<tr>
		<td>用户名</td>
		<td><input type="text" id="username" name="username"></td>
	</tr>
	<tr>
		<td>密码</td>
		<td><input type="password" id="password" name="password"></td>
	</tr>
	<tr>
		<td>确认密码</td>
		<td><input type="password" id="pwd" name="pwd"></td>
	</tr>
	<tr>
		<td><input type="button" onclick="validate()" id="ok" value="提交"></td>
		<td></td>
	</tr>
</table>
</form>

后台处理:

 

<?php
header ( "content-Type: text/html; charset=GBK" );

$username = $_POST ["username"];
$password = $_POST ["password"];
//mb_convert_encoding($username,"utf-8");

$conn = oci_connect ( 'testphp', '123', 'ORACLE11' );

$statement = oci_parse ( $conn, "insert into userinfo values(idauto.nextval,:username,:password) RETURNING ROWID INTO :id" );

$rowid = oci_new_descriptor ( $conn, OCI_D_ROWID );

oci_bind_by_name ( $statement, ":username", $username, SQL_VARCHAR );
oci_bind_by_name ( $statement, ":password", $password, SQL_VARCHAR );
oci_bind_by_name ( $statement, ":id", $rowid, - 1, OCI_B_ROWID );
if(oci_execute ( $statement)){
	echo $username." ".$password;
}
oci_commit ( $conn );
$rowid->free ();
oci_free_statement ( $statement );
oci_close ( $conn );
?>

这个insert我看了N久的代码,oci上面写的还比较完整,网友也给予一些提示。

为什么页面是GBK格式?因为我插入Oracle的话,utf-8是乱码,GBK就没事,这个问题先这样解决,以后想想如何在utf-8的页面格式下插入数据库

insert语句插入数据库时传参方式和hibernate有点相似,也是冒号:设置参数,不同的是处理sequence上,hibernate在配置文档中写好,php写在sql语句中,估计用到框架的话,也不用再写idauto.nextval了,id是sequence的值,需要我们用oci_new_descriptor 规定一个新的描述,oci_bind_by_name 相当于hibernate的setQuery语句进行传参复制,我甚至怀疑php天生就是防注入的。好了就是这样,update和delete再准备做实验

Sep 2
Jul 17

115网盘上面的

Jun 25

 

在DBHelper类中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace MySchool                                                                     //MySchool是我的项目名称
{
    class DBHelper
    {
        static string conString = "Data Source=服务器名;Initial Catalog=数据库名;User ID=sa";                                        //我选择的是windows+sql混合验证,登录名sa,如果有Pwd还需要添加
        public static SqlConnection con=new SqlConnection(conString);                                                                                //创建SqlConnection对象,用于连接
    }
}

 

然后在另一个类中(比如窗体类)可以调用
using System.Data.SqlClient;
string sql = "select * from teacher";                                                                       //输入的sql命令
SqlCommand cmd = new SqlCommand(sql,DBHelper.con);                        //创建SqlCommand对象,导入sql命令,连接的是DBHelper中写好的数据库
DBHelper.con.Open();                                                                                             //打开数据库
SqlDataReader dr = cmd.ExecuteReader();                                                       //创建SqlDataReader类对象,用于一行一行读取数据库中数据
dr.HasRows                                                                        //在数据库中执行select * from teacher,会有多行受到影响。如果有影响,HasRows返回true,否则返回false
dr.Read();                                                                                //读取一行数据,若想一遍一遍的读,一直到读完为止,则可以写到while语句中
string loginid = dr["LoginID"].ToString();                            //把数据库中字段LoginID的第一个记录给字符串loginid
Jun 17

这里真是个蛮清净的地方,但我始终没有想起这个地方

也许很久没有接触代码,就像语言一样,一天不接触,第二天就会生疏

拿起许久没有接触的java,就不想去想别的事情,坐在那里编程

VS+sql server是我最近经常使用的

但我从心里感觉不到快乐,也许是出于版权的意识

我还是很喜欢linux

要在linux下找到同样功能强大的平台

老一代的编程学者用着vi并且乐此不疲

Eclipse还有QT,我相信它们的实力

不希望以后做出来的东西,仅仅用在windows下,是否跨平台,永远是我最最关心的

Jun 12

做个测试使用

Oct 25

空荡荡的不太合适,写点东西吧,以后就在这里写一些关于编程的文章,以及我们的回力标计划