Project1.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1); //调用这个vcl模块,详见Unit1.cpp
//---------------------------------------------------------------------------
//这里很搞笑,没给参数名重写,不知道这样函数里面能不能用到这几个参数
//不过好像也就没用
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
//The owner of the new form is the Application object
//__classid返回一个指向TForm1的vtable的指针,这点还要再看看实现过程
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch ()
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
Unit1.h:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
//都只是些声明部分,所以包含在头文件里面
#include <Classes.hpp> //TPersistent, TComponent
#include <Controls.hpp> //TControl, TWinControl
#include <StdCtrls.hpp> //TButton
#include <Forms.hpp> //TApplication, TForm
//---------------------------------------------------------------------------
/*
TObject(RTTI,垃圾回收等最基本的)
|
|--TList(stores an array of pointers)
|
|--TStream(read and write to some media)
| |
| |--TFileStream,TStringStream,TWinSocketStrem
|
|--TFiler(读写控件[objects]属性:比如保存dfm文件信息,在内存中暂存控件信息等)
| |
| |--TReader
| |--TWriter(具体实现Filer功能)
|
|--TPersistent(have assignment and streaming capabilities)
|
|--TStrings(for objects that represent a list of strings)
| |
| |--TStringList(具体实现)
|
|--TComponent(控件父类,包括可显示和不可显示)
|
|--TApplication(抽象WindowsGUI环境,消息机制当然还有针对web的环境)
|
|--TControl(可视控件)
|
|--TWinControl(针对Windows的可视控件)
|
|--TButtonControl(Button的抽象)
| |
| |--TButton(Button的具体实现)
|
|--TScrollingWinControl(支持滚动条的Windows控件)
|
|--TCustomForm
|
|--TForm
*/
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner); //Owner是创造者,Parent是呈现者(只对于可视控件)
};
//---------------------------------------------------------------------------
/*
把这个vcl(Form1)导出,其他模块使用这个头文件时就告诉编译器,这个vcl在别处具体定义
*/
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop //之前的头文件可以使用头文件缓存技术,其他包含vcl.h的编译块就编译一次
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
/*
这里的疑问在于,头文件里面已经有一个extern的指针,这里为何还要再次搞出个指针.
注意在Project1.cpp里面有个USEFORM的宏,这个宏的具体定义在vcl\sysclass.h文件中
如下:
#ifdef BCBVER1
#define USEFORM(FileName, FormName) \
class DELPHICLASS T##FormName; \
extern T##FormName *FormName;
#else
#define USEFORM(FileName, FormName) \
class DELPHICLASS T##FormName; \
extern PACKAGE T##FormName *FormName;
#endif
可以看出这里FileName根本没用上,所以"既然给了cpp也就给了.h也就给了那个extern指针"
的想法是错误的,cpp文件根本就没有起到任何作用,还是完全依赖连接时靠extern的存储
属性在obj里面去找.这也就是为什么cpp里面如果没有下面这个指针声明,报错的不是Unit1
而是Project1,因为是在Project1调用了这么个没有定义个指针.还有一点就是,之所以会这
样是因为.h是不会编译的,Project1在Unit1.cpp对应的obj里面去找,当然找不到.所以这里
必须要再次写上一句.
*/
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------