实现MFC编译时多语言方案
http://blog.csdn.net/John_Yang/archive/2010/05/02/5549400.aspx
关键是定义 AFX_RESOURCE_DLL 和 AFX_TARG_GNU (具体语言不同)
posted @
2011-03-22 14:26 张志松 阅读(950) |
评论 (0) |
编辑 收藏
IE首页自动打开
http://runonce.msn.com/runonce3.aspx在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main下新建DWORD值,命名为DisableFirstRunCustomize,并修改其值为1。
IE新选项卡about:Tabs
在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TabbedBrowsing右侧窗口新建一个DWORD值,重命名为ShowTabsWelcome,将它的值设为0。
posted @
2011-03-19 13:35 张志松 阅读(202) |
评论 (0) |
编辑 收藏
在网上经常能看到 一些评论和比较C#、VB.net优劣的文章。其中绝大多数都认为:VB.net就没有它存在的必要,VB.net迟早要被C#取代。
确实,计算机语言不是很重要的,也许讨论它有点无聊。所以还希望那些“心中无剑”、“架构、思想至尚”的高手们口下留情。
关于VB.net与C#在功能、能力、面向对象的特性上,实在是难分伯仲。这个已是不争的事实。尤其是VS.net2005中,这两种语言已经达到了惊人地相似!
下面就通过三个大方面对这这两种语言进行比较:
一、语言的人性化区别
C#像傻男人,VB.net像聪明贤惠的女人
从代码的风格就可以看出。
例1. 声明变量时:
C#: int iTest ; //很直接的语气,类似于:擦汗!拿毛巾
VB.net Dim iTest As Integer ‘很委婉的语气,类似于:小王,给我拿条毛巾,我用它擦汗~
实现完全相同的功能,但有着很明显的区别。哪个更人性化、更易懂呢?
例2.语言的关键字上:
C#关键字:
using、this、void、base、abstract、sealed、virtual、switch、internal、static
相应的VB.net关键字:
Imports、Me、Sub、MyBase、MustInherit、NotOverridable、MustOverride、Select 、Friend、Shared
比较一下,C#的关键字比较冰冷,是具有一定“机器味道”的语言。
而VB.net的关键字,都是“人的行为”,“人的称谓”。
相信VB.net的语法更具亲和力,更易于帮助我们理解面向对象的特性。
二、语言的先进性的对比
现在,计算机软件工程越来越庞大,已经远远不是10年前的几十KB大小的级别了。这就对语言的可扩展性、可辅助性提出了更高的要求。“面向对象”便是这个需求的一个产物。
从现有的语言来看,具有“标识符”的标识性语言具备更高的容错性、可调试性、可扩展性。比如HTML、XML。尤其是XML已经成为了下一代语言的模型。
为什么像HTML、XML这种具有“开口”和“封口”的语言 有更高的容错性、可调试性呢?这要取决于它的“吝啬”性。“开口”和“封口”可以把故障的范围最小化,使出现问题的部分尽量不影响其它部分。比如说:在HTML的<table>中,少写一个<TR>多写一个<TR>均不会对表格中其它行造成太大的影响。
与 这种“吝啬”的语法相反的是“贪婪”性的语法。什么是“贪婪”性呢?这个问题也不太好解释。不过,这种特性与正则表达式的解析十分十分地一致。“吝啬性”的正则表达式 用做 精确匹配Group时有着较高的性能,而“贪婪性”的正则表达式用于判断IsMatch时有着较高的性能。
像C类的所有封口均使用大括号的语言,就属于这种“贪婪性”性的语言。过多相同的封口使得代码更加地难于控制。
许多人抱怨微软,为什么不给C#加上动态编译、加上自动完成……,实际上,微软何尝不想加啊,但由于C#的语法特性,是根本无法实现的。下面就用实例来说明为什么C#无法实现动态编译:
看下面的C#代码段,代码中的大括号是不平衡的:
class A {
class B {
class C
{
int F1()
{
return 1;
}
int F2()
{
return 2;
}
}
}
假如现在已经有了C#的动态编译器,现在要求编译器指明到底是哪里丢失了大括号!
这时,编译器就糊涂了:因为 不论是把大括号加在F1的末尾 还是加在class A的末尾 都是行得通的,虽然这两种情况的意义是完全不同的,即:不能判断F1到底是Class C的方法,还是Class B的方法。那么连带下一步,在代码的其它部分 就更无法判断 调用F1的代码的合理性了。
这里只是举了一个简单的例子,实际的情况比这个更复杂。我们可以看到,在C语言的代码没有完全正确地书写之前,它的结构是有可能极度混乱、多意性的,在这种极度混乱的环境下 是无法判断故障之所在、无法正确识别对象的结构的。自然,这样的动态编译器也就成了“累赘”。
相比之下,同样的内容 看看VB语法:
Class A
Class B
Class C
Function X1() As Integer
Return 1
End Function
End Class
Function X2() As Integer
Return 2
End Function
End Class
End Class
无论你删除End Class还是删除End function,故障范围都不会扩大,定位就可以做到精准。
检错如此,自动完成代码也是如此。在C#环境下,由于代码结构可能存在着“多意性”,所以IDE有可能无法决定做处理的确切位置。
当然,C类的代码并不是没有优点,其优点主要有二:
1.节省代码所占的磁盘和内存空间
2.使编译器的体积能够做得更小(最终还是为了节省磁盘空间)
只有在 内存和磁盘空间非常珍贵的过去的年代里,C类语言代码才能够更具优势。
然而在内存和磁盘如此丰富的今天,这种优势已经成了劣势。
借助于这种具有确定的“开口”与“封口”的特性,相信VB.net会走得更远。
三、语言的灵活性、适应性的对比
C#的代码,可以“随便书写”:在一行里可以写多条语句,一条语句可以分成多行来写。这使得它的代码有可能更加地“松散”。虽然C#允许您把代码写得非常地松散,不过在实际的使用中,几乎所有的使用者都默默地走向了VB的代码风格(一行一条语句)。最后,它的分号成了累赘。
虽然C#的代码更加地自由,不过C#的思想比起VB.net起来却是更加地死板。
在这方面,我觉得把C#比做手动档汽车、把VB.net比做自动档汽车是比较合适的。自动档汽车也可以用手动档的方式驾驶。
C#的思想、思路在VB.net中均可实现,而VB.net的思想(自动档)却经常无法在C#上实现。下面举例说明:
例一:事件模型
在C#中,事件模型是固定的,构造一个事件模型通常需要下面的思路:
建立事件代理结构、声明事件、建立事件处理方法、添加事件句柄、判断事件代理是否挂到上实例、通过代理方法引发事件。
在VB.net中,即可以按照C#所用的模式建立事件,也可以用VB.net自身所带的RaiseEvent方法实现。虽然他们编译后的结构几乎是一样的,但毕竟VB.net让我们有了更多的选择,何乐而不为呢?下面就看看VB.net引发事件的两种方法示例:
方法一:用RaiseEvent.
这是一种非常快捷、代码思路非常清晰的一种方法:
Class EventClass
Public Event E1(sender as Object,e as XXXEventHandler)
Sub XXXX()
RaiseEvent E1(Me,new XXXEventHandler(…)
End Sub
End Class
方法二:用C#的的思路
Public Delegate Sub xxxHandler(ByVal sender As Object, ByVal e As EventArgs)
Public Class A
Public Event XXX As xxxHandler
Public Overridable Sub OnXXXEvent(ByVal sender As Object, ByVal e As EventArgs)
If XXXEvent IsNot Nothing Then
XXXEvent.Invoke(sender, e)
End If
End Sub
Sub X()
OnXXXEvent(Me, New EventArgs)
End Sub
End Class
“用尽量少的代码 做出更多的事情”是每个人程序员的最爱!
很显然,VB.net在这方面占尽了优势。
例二:可选参数结构
如下代码展示了VB特有的结构:可选参数
Public Sub XXX(P1 As Integer,Optional P2 As String,Optional P3 As String)
‘…
End Sub
这样的结构在C#中是无法实现的,但可以通过“重载”的方式实现相同的效果:
void XXX(int P1){}
void XXX(int P1,string P2){}
void XXX(int P1,string P2,string P3{}
当然,用VB.net也可以用重载方式写出一模一样的结构。
例三:事件代理的挂接
C#中:只有一种方法:XXX.XXX += new XXX(…);
VB.net中:即可以效仿C#的方法:AddHandler(XXX.xxx,AddressOf XXX)
也可以把过程显示地指定给某个事件:Sub(…) Handles XXX.XXX
利用上面的第二种方法的特性,可以实现在VB.net代码编辑页中 简单地通过下拉框 来精确地定位某个对象的特定事件的处理过程。
遗憾的是,这种方便的特性在C#中是无法实现的。因为C#的语法:XXX.XXX +=的后面可以是任何方法返回的具有相同签名的实例。比如 通过属性、方法,甚至是随机判断后返回的。
这种“过份的自由”使得C#编译器在运行代码前不能准确地确定该对象事件的处理部位。
类似的例子太多了,举不胜举。
总之,VB.net给了我们更大的活动空间,它允许我们在“更快的速度”和“更严格性能要求”之间自由选择。
四、代码书写上的比较
一、变量的命名的区别
C#是区分变量的大小写的,这一点着实让人摸不着门。也许这仅仅是为了效仿Java?
在公共语言规范中(CLS),明确规定“变量不区分大小写”的,真是难为了C#编译器,还要把“重名”的变量重新命名。
相比之下,VB.net更加符合CLS,而且因为不区分大小写,编辑器就更轻松地实现了“自动更正”功能。
C#绝对是“嫁错了人”。
C要区分大小写,其原因有二:一是为了能使用更多的变量资源,二是为了节省编译器的开销(性能和体积上都节省)。
如今,.net环境允许我们使用多达1024个长度的变量名,而且已完全面向对象化,相同的变量可以同时出现在任何object中,所以可用的变量资源数量 理论上已经达到了无穷多个!
在这样的条件下,“区分大小写”使代码在 可读性、可调试性、可辅助性上都造成了不小的负面影响!它已经成为了语言发展的障碍!
二、代码的书写
几乎绝大多数的C#程序员都觉得他们在代码的书写上有着无与伦比的优越性,因为C#代码看上去是如此的简洁。
是的,如果我们仅使用记事本来开发.net应用程序,我相信像VB、Delphi早就灭绝了。
但更糟糕的是:如果我们仅能使用记事本写代码,那么程序员也早就集体自杀了。
说多少也不会有人相信,尤其是C#程序员不会相信 在代码书写方面 他们会完败于VB.net程序员。
我们完全可以用“键盘钩子”做个小程序来检测、验证一下到底是哪种代码更浪费键盘、书写起来更吃力。(这个程序我已经写好,有兴趣的可以到http://img.pcpop.com/upimg2/2005/5/15/491525800.jpg 来下载。注意:必须使用网络快车下载,下载后把文件更改为exe的即可直接运行。这个序使用VB.net + Framework1.0编写,必要的时候 需要你安装.net框架。)
测试结果很明显:VB.net代码需要按键的次数更少、书写更为容易。原因是IDE在其中起到了极大的作用!
VB.net不必像C#那样不停地用Ctrl+shift+B来编译检错;不必不停地按下Shift键来输入星罗棋布的符号;不必不停地使用Ctrl+]徘徊于大括号之间;更不必手动输入众多的“关闭符”。
(试一试:输入If A=B [回车],这时 Then和End IF马上就都给你准备好了)
(再试一试:在一个刚刚建立的新Class中,输入Inherits后 回车,所有需要实现的方法都给你准备好了)
究其本质,是由于VB.net的语言起到了决定性的作用。
正是因为我们已经告诉了编辑器“这是一个ReadOnly Property”,所以编辑器会给我们自动提供了Get结构代码;
正是因为我们已经告诉了编辑器“这是一个WithEvents的对象”,所以编辑器会在对象事件选择列表里加入它;
正是因为我们已经告诉了编辑器“这是一个Event”,所以当我们要RaiseEvent时,它会准确地出现在列表中;
正是因为我们已经告诉了编辑器“这是一个Function”,所以当我们写上调用方法后,它会自动地在后面加上括号;
……
反观C#,由于代码过度地萎缩,许多事情还需要通过分析整段代码的结构来决定它的属性,导致这些“智能的操作”无法在C#上实现。
但这些动词并不能表明VB.net和C#之间具有什么差距!!!!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/panjun_websoftware/archive/2008/02/28/2129117.aspx
posted @
2011-03-09 13:47 张志松 阅读(5499) |
评论 (1) |
编辑 收藏
引用Microsoft OLE DB Service Component 1.0 Type Libary
Dim objDataLinks As DataLinks
Set objDataLinks = New DataLinks
'Set objDataLinks = CreateObject("DataLinks")
objDataLinks.hWnd = Me.hWnd
Dim obj As Object
Set obj = objDataLinks.PromptNew
If Not obj Is Nothing Then
Dim strConn As String
strConn = obj
MsgBox strConn
End If
Set objDataLinks = Nothing
posted @
2011-03-07 16:26 张志松 阅读(463) |
评论 (0) |
编辑 收藏
MSDN:
If a thread calls LeaveCriticalSection when it does not have ownership of the specified critical section object, an error occurs that may cause another thread using EnterCriticalSection to wait indefinitely.
比如在MFC中使用
CCriticalSection m_MyCriticalSection; // 模块级变量
在某个函数中:
CSingleLock lock(&m_MyCriticalSection, TRUE);
//使用下面这行代码提前解除锁定,将会导致死锁,
//因为CSingleLock 的虚构函数还会调用一次m_MyCriticalSection.Unlock()
//m_MyCriticalSection.Unlock();
//要使用下面这行代码代替,因为这样CSingleLock 的虚构函数不会再调用m_MyCriticalSection.Unlock()
lock.Unlock();
posted @
2011-02-14 13:47 张志松 阅读(4034) |
评论 (0) |
编辑 收藏
运行里面输入 regsvr32 itss.dll 后按确定即可。
posted @
2011-02-13 18:48 张志松 阅读(462) |
评论 (0) |
编辑 收藏
1.调试脚本
CScript.exe /X xxx.vbs
WScript.exe /X xxx.vbs
运行后会弹出实时调试对话框,选择你要使用调试器后就可以进行调试了。
2.调试ASP
IIS5.1需要附加dllhost.exe到调试器。
posted @
2011-02-11 21:24 张志松 阅读(268) |
评论 (0) |
编辑 收藏
WS_EX_NOACTIVATE
BOOL CNoActiveWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
//可以创建时直接使用标志WS_EX_NOACTIVATE
if (!CreateEx(WS_EX_APPWINDOW | WS_EX_NOACTIVATE, lpszClassName, NULL, WS_POPUP | WS_VISIBLE,
10, 10, 100, 100, NULL, NULL, NULL))
{
return FALSE;
}
//也可以创建后修改
//ModifyStyleEx(0, WS_EX_NOACTIVATE);
}
posted @
2011-02-11 15:17 张志松 阅读(1357) |
评论 (0) |
编辑 收藏
由于每个WIN32进程拥有独立的地址空间,所以写远程线程函数不像写本地线程函数那样简单。
这里提供一个办法,像写本地线程函数一样写远程线程函数。(下载头文件和LIB文件)
/**
*创建远程线程
*/
HANDLE CreateRemoteThreadEx(
HANDLE hProcess, //目标进程句柄,拥有PROCESS_ALL_ACCESS访问权限。
HMODULE hModule, //线程函数所在的模块,可以是EXE(直接传NULL)也可以是DLL。
LPTHREAD_START_ROUTINE lpStartAddress, //线程函数地址。
LPVOID lpParameter //线程函数参数,可以为NULL。
);
例子:
#include "stdafx.h"
#include <Windows.h>
#include "RemoteThreadLib.h"
//修改默认基址
#pragma comment(linker, "/BASE:0x13150000")
//远程线程函数
static DWORD WINAPI ThreadFunc(LPVOID pData)
{
while (TRUE)
{
//这里可以调用WINDOWS API以及你自己在这个模块里实现的函数和类等。
OutputDebugString("ThreadFunc");
MessageBox(NULL, "My Remote Thread Message!", "RemoteThreadLib", MB_OK);
Sleep(5 * 1000);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
EnableDebugPrivilege(TRUE); //提权
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 4000); //从任务管理器找一个进程ID,比如记事本
if (hProcess != NULL)
{
HANDLE hThread = CreateRemoteThreadEx(hProcess, GetModuleHandle(NULL), ThreadFunc, NULL);
if (hThread != NULL)
{
//成功
}
CloseHandle(hProcess);
}
return 0;
}
VS2003+XP下调试通过!
posted @
2011-01-28 11:56 张志松 阅读(529) |
评论 (0) |
编辑 收藏
//首先获取当前鼠标的位置
CPoint point;
GetCursorPos(&point);
//计算要点击的位置,将像素坐标转换鼠标能认识的坐标
DWORD dx = 200 * 65536 / GetSystemMetrics(SM_CXSCREEN);
DWORD dy = 200 * 65536 / GetSystemMetrics(SM_CYSCREEN);
//移动鼠标,模拟点击鼠标左键
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,
dx, dy, 0, GetMessageExtraInfo());
//恢复鼠标到原来的位置
SetCursorPos(point.x, point.y);
posted @
2011-01-27 13:17 张志松 阅读(1592) |
评论 (0) |
编辑 收藏