星期六, 五月 19, 2007

#define conclusion

Macro can be thought as a mechanism of replacement in C++.

1. Basic #define
We can use it as a way of text replacement.

#define POPULATION 1200000

When we are compiling it, we will replace every POPULATION to 1200000 in the following code.

2. Function Definition
#define can receive parameters as Funcitons.

#define max(x,y) (x)>(y)?(x):(y);

This function returns the bigger number. However, since without type detectation, it's more like funciton template. But there is still some fault.
For example:

#define ADD(a,b) a+b;

When you encounter code c*ADD(a,b)*d, the factual calculating process becomes c*a+b*d, not c*(a+b)*d. That's a big problem

Another emaple:

#define pin(int*);
pin a, b;


When you call the macro, you mean to indicate both a and b are int pointers. But factually, it is int*a, b, which means a is an int pointer, but b is int

type. Therefore, you should use another way typedef to replace define.


3. Macro Single line Definition

#define A(x) T_##x

if x = 1, then A(1) ======== T_1

You must be surprised by the result. Here "##"means combination. When you call this macro, the result is to combine T_ and x. Here x=1, so the result is T_1.

4.Macro Multilines Definintion

Many lines of #define is available. In MFC, this kind of method is constantly used.

#define MACRO(arg1, arg2) do { \
/* declarations */ \
stmt1; \
stmt2; \
/*........*/ \
} while(0) /* (no trailing ; ) */

Do not forget to add "/" after every line.

5.Condition Compiling

#ifdef WINDOWS
...............
...............
#endif
#ifdef LINUX
..............
..............
#endif


You can #define to setup compiling enviroment.

5. How to define Macro and cancel Macro

//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
//普通宏
#define PI (3.1415926)
//带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))


6.Macro combination

## is to combine two macros
# is to replace the name with string

For example

#define s5(a) supper_ ## a
#include
void supper_printf(const char* p )
{
printf("this is supper printf:\n%s\n",p);
}

int main()
{
s5(printf)("hello owrld");
return 0;
}

Result:
This is supper printf:
hello world

Example
#include
#define s(p) #p

int main()
{
printf(s(p)"\n");
return 0;
}

Result:
p

# can be uesd to constrain it a parameter to become a string.

星期二, 四月 24, 2007

The Route of Command Processing

After you have pressed a Button in Windows, how does Windows System process the events, I think, is an amazing part when you learn to code under MFC.

Firstly, you should know three important functions. CWnd::WindowProc, CWnd::OnWndMsg, and CWnd::DefWindowProc. When your Windows system starts, the crucial shell process, explorer.exe, is always running to capture every little change of your computer. When a button is clicked, Windows always sends a WM_COMMAND message to Parent Windows. And CWnd::OnWndMsg function is to define the type of received message. CWnd::WindowProc can process all received message. CWnd::WindowProc calls CWnd::OnWndMsg, and decide whether call CWnd::DefWindowProc depending on the return value of CWnd::OnWndMsg.

LRESULT CWnd:: WinodwProc ( UNIT message, WPARM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
If ( !OnWndMsg (message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}

Two parameters, wParam and lParam should be noticed. Parameter wParam contains two values, which the lower one is the ID resource of menu, control, and shortcut, and the higher one express the message information (BN_CLICKED expresses a button is clicked). Parameter lParam indicates the window handler of the controller.


When the message is WM_COMMAND, CWnd::OnCommand function is called and its return value is sent to CWnd::WindowProc.

CWnd::OnCommand checks the validity of the message, such as whether the return value is 0, whether the controller has been disabled. After checkout, CWnd::OnCommand sends a message to the controller. Finally, CWnd::OnCommand calls CDialog::OnCmdMsg, and CDialog::OnCmdMsg will call CCmdTarget::OnCmdMsg.

CCmdTarget is a base class of MFC. When a message is sent to a Dialog, a default route appears: firstly the message is sent to Dialog, and then to Dialog window. Finally, it is sent to an application object.

Finally, how to combine the controller and the processing function is a main point to concern. When you open the source file of your Dialog, for example, dlgcore.cpp, and search for BEGIN_MESSAGE_MAP, the following code appears:

BEGIN_MESSAGE_MAP (CDialog, CWnd)
//{{AFX_MSG_MAP(CDialog)
ON_COMMAND(IDOK, OnOK)
ON_COMMAND(IDCANCEL, OnCancel)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
ON_MESSAGE(WM_INITDIALOG, HandleInitDialog)
ON_MESSAGE(WM_SETFONT, HandleSetFont)
ON_WM_PAINT()
//}} AFX_MSG_MAP
END_MESSAGE_MAP

This is the table of message mapping. You can find the processing function and the ID resource are combined by this way. A virtual function GetMessageMap, which is defined in extended Macro _messageEntries, is used to find a proper function entry from upper table.

This is the basic process of message cycling in MFC.



星期二, 四月 17, 2007

MFC - The Hell of UI Design

In the past week, I have spent almost all of my spare time on studying progrmamming on Visual C++. However, I don't think it's a friendly platform to support our developers to design UI as quick as possible.
Firstly , we can to stuyd the ugly MVC-liked documents structure. We have to distinguish which is good for single view from multiview. And we need to keep clear when we are puzzles by trememdous definitions and clarifications. After we have grab the last straw to find the application is not avalaible, we have to cry out for god's sake : who have designed MFC.
Then the complex calls and IDs become another nightmare for everyone who want to design UI in a quick pace. Comparing to .net Framework, I don't see the value fo MFC. And I think, many developers have already given up MFC. Only the people who want to maintain some old code have to endure the low effetiency of it.
MFC, it's impossible for me to love you

星期四, 三月 22, 2007

《物权法》和司法独立

《Economics》上面介绍《物权法》的配图

今天看了《Economics》上介绍中国人大通过《物权法》的文章《China's next revolution》,文章分析了本法律颁布后的三个方面的问题:1、不能完全解决由于开发需要的全部物权问题;2、无法清晰界定物的实际归属权;3、没有司法制度的改革,无法确保司法执行。文章最后说道:Were the latter writing today, he would surely see in China a revolution waiting to happen—or perhaps two. One is the bourgeois revolution led by the emerging property-owning middle class that the new law will help. The other is the potential for the simmering resentment in the countryside to boil over, perhaps in frustration at the law's shortcomings.

《物权法》的颁布,有一个很强的时代背景,就是大量的由于征地的纠纷以及中产阶级对私有财产保护的诉求。时间进入20世纪90年代以后,房地产开始在各地兴盛,许多开发商同政府官员勾结,廉价收购国营企业的土地,以极其廉价的方式让大量工人下岗,然后将原先的厂房推倒后,就地搞房地产。大量下岗的职工由于失业,成为社会的下层人民的代表,并且给社会带来严重的影响和社会贫富不均。随着70年代末80年代初的一代青年人渐渐走入社会,成为社会消费的主导,他们对于财产的观念已经不同于上一辈人,他们更希望自己通过白手起家而得到的房屋权,可以得到法律的保护。

虽然《物权法》被誉为中国现代法制史上的一个转折,并且成为许多左翼人士叫嚣数典忘祖的靶子,不过他的通过是不可逆转的。财产权的保护,如果说是公民的基本权力。那么他比什么言论自由,比什么民主公平更加重要和实际。没有一个人愿意看着自己辛苦一生的房子,在政府莫明其妙的城市规划中夷为平地,也没有人愿意看到自己辛苦一辈子最后发现都在给共产党打工。所以,公民对于土地的权力就像自由一样,是“天赋”的。

我想我们这一代人,是拥有独立人格和思想的一代。已经不再是“领导大手一挥,我们提着裤子跟着追”的时代。那么随着曾经被忽视和剥夺的许多权力的回归,必然会产生新的政治诉求。而我们这一代拥有独立人格和思想的一代人,必然会成为中国政治改革的强有力推动者。而对于政治的诉求,必然需要司法的独立性来避免由于对于政治诉求而产生的许多法律问题和冲突。而司法的独立性必然成为追求自由和发展的80后人的一个政治诉求。

如果《物权法》的颁布是中国政治改革的启明星,那么我们希望,我们这一代的所有人,都能成为中国这个伟大变革开始的见证人。