檢視 DLL 提供的函式 E:\WINNT\system32>dumpbin /exports user32.dll Microsoft (R) COFF Binary File Dumper Version 5.00.7022 Copyright (C) Microsoft Corp 1992-1997. All rights reserved. Dump of file user32.dll File Type: DLL Section contains the following Exports for USER32.dll 0 characteristics 336A2A2A time date stamp Sat May 03 01:53:46 1997 0.00 version 1 ordinal base 634 number of functions 634 number of names ordinal hint name 1 0 ActivateKeyboardLayout (00015B1A) 2 1 AdjustWindowRect (0000D704) 3 2 AdjustWindowRectEx (00007D8E) 4 3 AnyPopup (00043ABB) 5 4 AppendMenuA (00011F57) 6 5 AppendMenuW (0002D7A4)
RAD 無罪,輕鬆有理不論是哪套 application framework ,一定會力有未逮,包裝不足時,此刻,是 RAD 也好,不是 RAD 也好,任何工具幫不上忙,只有瞧自己琢磨 Win32 API 的功夫。若沒有三兩下子,馬腳隨著 framework 的不足就立即露出了。 手工打造的好,還是拖拉點放的方便?手工打造的快,還是拖拉點放的省事?我想答案是很明顯的 易使初學者陷入迷途是 RAD 的原罪,但 RAD 所帶來的好處豈容輕易抵消。 RAD 無罪,它只是使門檻降低點,讓程式設計更為簡單輕鬆,何罪之有?
34.
C++ Language Theevolution of programming paradigm The definition of object-oriented programming Why object-oriented programming ? The C++ programming language
35.
Programming Paradigm Howwe think and write programs ? program domain problem domain The evolution: procedural programming modular programming ADT programming object-oriented programming generic programming
36.
Procedural ProgrammingParadigm FORTRAN, C, Pascal There are many procedures (operations) Data is placed at global areas or inside procedures Procedures are designed to process data Program = data + procedures which process the data
37.
ADT Programming ParadigmCLU, Ada, Module-2 ADT (abstract data types) programming is also called object-based programming Encapsulate operations and data inside objects Program = objects and their interactions
38.
Object-Oriented ProgrammingParadigm Simula, Smalltalk, Java 以繼承 (inheritance) 和動態繫結 (dynamic binding) 擴充了 ADT 繼承 : 既有實作碼的重複運用 動態繫結 : 既有之公開介面的重複運用 C++ is a mixed-paradigm programming language
C++ 的由來西元 1980 年, Bjarne Stroustrup 發明了 "C with Classes" 語言,因為他想為 C 語言加入如同 Simula67 語言般的事件驅動機制。直到 1983 年夏天,才由 Rick Mascitti 創造出 C++ 這個語言名稱。
44.
如何看待 C++? 如果你懂得 C 語言,那麼可以這樣看待 C++ 語言: 它是比較好的 C 語言 它提供資料抽象化機制 它支援物件導向程式設計,所提供的語法及字眼讓你可以很輕易地將物件導向精神落實到 C++ 程式中 C++ 語言的功能強大,無庸致疑, template 、 exception handling 、 RTTI 、 Standard Library 等等功能不斷地加強翻新。由於使用者眾,要求必多,期望必高,再加上 C++ 本身定位在功能強大範圍廣泛的通用性語言,如江海之納百川, C++ 自然日益複雜。
45.
強大複雜的 C++著名的雜誌 C++ Journal 上曾有段話: 雖然是最流行的物件導向程式語言,但除非你有足夠的耐心及精神來全盤掌握它,否則輕易嘗試的後果可能只會得到一臉的挫折。當然囉,十分的複雜也帶來十分的便利及高度的成就感及樂趣,端視你如何取捨。 如果你認為 C++ 還不算太複雜,那麼請你解釋何謂 protected abstract virtual base pure virtual private destructor ,而你又會在何時需要它呢? Tom Cargill C++ Journal Fall 1990
46.
強大複雜的 C++並不是語言中的每一項特質都要成你的下一座攀爬目標。究竟要不要使用某項性質 , 我們應該以程式的邏輯做決定 , 而不是只因為它在那裡。 -- C++ Primer
47.
C++ 類別宣告使用 class 關鍵字。 類別裡可以加入任意數目的變數及函式宣告。 建構函式與類別名稱相同。 解構函式為類別名稱前頭加上 ~ 。 class TMyClass { int a, b, c; TMyClass(<parameters>); // 建構函式 ~TMyClass(void); // 解構函式 void draw(); int draw(int x, int y, int z); };
TMammal 類別TCat 及 TDog 類別 TMammal and child classes class TMammal { private : AnsiString FName, FEyeColor; int FAge; public : __fastcall TMammal( void ); virtual void __fastcall Speak( void ) = 0; }; class TCat : public TMammal { virtual void __fastcall Speak( void ) {ShowMessage(“I’m Cat”);} }; class TDog : public TMammal { virtual void __fastcall Speak( void ) {ShowMessage(“I’m Dog”);} };
50.
在累堆建立 TCat 及 TDog 物件 呼叫 TMammal 類別宣告的 Speak 函式 由於多型機制,兩個物件呈現不同的結果 The Power of Polymorphism void __fastcall TForm1::Button1Click(TObject *Sender) { TMammal* Mammal = new TCat (); Mammal->Speak(); delete Mammal; } void __fastcall TForm1::Button2Click(TObject *Sender) { TMammal* Mammal = new TDog (); Mammal->Speak(); delete Mammal; }
51.
C++ Enhancement forBCB The new keywords adds to C++Builder New class scoping options in C++Builder How C++Builder includes DFM resources in projects How to use open arrays in C++Builder How to handle VCL exceptions How to throw VCL exceptions How to create your own custom VCL exceptions
52.
Added Keywords Newaccess specifier for classes __published __automated __fastcall modifier for methods
學習 VCL 類別架構 由於物件導向的繼承特性,類別庫(也就是包含一大堆類別的程式庫)比起一般的函式庫還要好記、好學。 假設我知道下列幾件事實: 我知道 TComponent 是元件的始祖,有 Name 及 Tag 兩個屬性。 我知道 TControl 是可視元件的始祖,有 Left 及 Right 兩個屬性,有 Show 及 Hide 兩個方法。 我知道 TButton 是元件,而且是看得見的元件,所以它一定是 TControl 類別的後代,也是 TComponent 類別的後代,因為 TControl 繼承自 TComponent 。 那麼,就可以歸納出結論- TButton 一定有 Name 、 Tag 、 Left 、 Right 四個屬性,也一定有 Show 及 Hide 兩個方法可用。
Real life samplesfrom the lecturer In development of real world application, design effort of a sophisticated component usually takes some portion time. A nice-look UI component can make your applications impressive. Ex. Office 97-like toolbar and sidebar, sliding down menu…etc. A well-designed functionality component can save you much time for modularization. Three samples from the lecturer.
119.
Sample 1 -TxColorMemo Inherited from TCustomControl (about 3000 lines) Scrolling functionality builtin Support ANSI color text / URL sensitive Syntax Highlighting Support all edit control messages OwnerDraw and WordWarp..
120.
Sample 1 -TxColorMemo Used in ChatRoom client Can also used on code editor (syntax highlighting), text viewer / editor, about box
121.
Sample 2 -TxMarquee Inherited from TGraphicControl (about 1000 lines) Internally use TTimer component to repaint itself Used in about box
122.
Sample 3 -TxHexEdit Inherited from TCustomControl (about 500 lines) Inplace Editing No scrolling functionality builtin => easy Just calculate position and draw texts Inside story: undocumented CreateFont() API usage ( fdwClipPrecision parameter)
123.
Sample 3 -TxHexEdit Used in Packet Sniffer, can be map between treeview and TxHexEdit Can used in file hex mode editor and file dumper
124.
Mechanisms behind RADEnvironment Run Time Type Information Provide all the necessary information of components to IDE and run-time library Streaming Save and restore component state and data into storage Messaging Provide interaction between IDE and programmer
125.
Don’t fooled bythe term “Run Time” Design time of application is run time of components Intention Examine and modify the published data of components in the development environment Helper of component persistence (streaming) Function target Data types used by published fields, methods and properties TPersistence descendent classes Run Time Type Information
126.
Run Time TypeInformation Affect Incredible RAD Intergrated Development Environment Put components into specialized DLL (package) Examine the data type and class information during program executing via code Negative affect Slightly enlarger the linked executables, though RTTI is useless to end users Snooper can extract useful information from executables
127.
Where is RTTI? It is stored in compiled units, executables or DLL files built with Delphi How to obtain RTTI data in code ? For common data types, use TypeInfo() pseudo-function (How we know that is a pseudo-function ?) and leave the problem to Delphi compiler. For objects, RTTI data is pointed by a pointer within virtual method table (VMT). We can use ClassInfo class method to retrieve this pointer.
128.
Unfold the RTTIData of Objects For a component P, we can obtain its PTypeInfo pointer by (P^ - 60)^. Of course, you can use ClassInfo() method simply. VMT structure: defined in System unit Pointer Instance Variable P: TMyObject Instance Data VMT Pointer ... Data field 1 Data field 2 Data field 3 Virtual Method Table ... -64 -60 -56 0 4 -4 ... Self Pointer Type Info Field Table Destroy First Virtual Method ... Init Table -76 PTypeInfo = ^TTypeInfo; TTypeInfo = record Kind: TTypeKind; Name: ShortString; {TypeData: TTypeData} end; Class function TObject.ClassInfo: Pointer;
129.
What’s Inside theTTypeInfo Structure Simply, a type name , type kind , and a large variant record type data . The meaning of type data structure depends on type kind: For Ordinal Type, it contains its minimum, maximum value. For Enumerated Type, it contains the value list. For Set Type, it contains the enumerated type info. For Method Type, it contains type info of all parameters and result type. ...
130.
The Advantages RTTITake to Programmers Check the relationship between objects. is and as operator Get information of published properties and events. We can know more than just name of properties and events. Extract source code level information of data types. Show set and class type info during execution.
131.
Use is Andas Operator is - test object if a descendent of a class as - if pass the test of is operator, then typecast, else raise a exception procedure TForm1.BtnTypeCastClick(Sender: TObject); begin if Sender is TMenuItem then ShowMessage(‘Menu: ’ + TMenuItem(Sender).Caption) else ShowMessage(‘Button: ’ + (Sender as TButton).Caption); end;
132.
Know More ThanJust Name Of Properties and Events Change the same property of all components on the form procedure TForm1.Button2Click(Sender: TObject); var I : Integer; PropInfo: PPropInfo; begin for I := 0 to ComponentCount - 1 do begin PropInfo := GetPropInfo (Components[I]. ClassInfo , 'Color'); if PropInfo <> nil then SetOrdProp (Components[I], PropInfo, clRed); end; end;
133.
Know More ThanJust Name of Properties and Events Check whether a component is data-aware. function IsDataAware(AComponent: TComponent): Boolean; var PropInfo: PPropInfo; begin // 檢查元件 AComponent 是否擁有 DataSource 屬性 PropInfo := GetPropInfo (AComponent.ClassInfo, 'DataSource'); Result := PropInfo <> nil; // 謹慎起見,檢查看看那個叫做 DataSource 屬性的型態是否為 TDataSource 或 // 其衍生類別 if Result then if not ((PropInfo^.Proptype^.Kind = tkClass) and ( GetTypeData (PropInfo^.PropType^).ClassType. InheritsFrom ( TDataSource))) then Result := False; end;
RTTI on DailyBasis 根據元件的屬性、事件及其型別來進行動作 enable/disable, common properties localization 省去打字的麻煩 (for enumerated and set types) GetEnumName() of TypInfo unit
136.
Streaming Streaming isa mechanism for persistence of components. Streaming makes it possible to save a component and restore it whenever necessary. Borrow the advantages of resource management. A DFM file is actually a standard windows resource file (.RES). Delphi executable files exactly contain the same resource.
Streaming Elements Threekey elements: TFiler , TStream and of course a component . TFiler is a never-used abstract class, VCL actually use its descent TReader and TWriter classes. Don’t forget RTTI - No RTTI, No Streaming.
139.
Streaming Mechanism ownwrite TWriter DFM file component TStream create WriteComponentRes function TStream.WriteComponent TStream.WriteComponentRes TStream.WriteDescent TStream.WriteDescentRes component component component component own component component component component Delphi RAD IDE / Programmer write
140.
Multi-Appearance of Formsobject Form1: TForm1 Left = 341 Top = 337 Width = 148 Height = 179 Caption = 'Form1' ... object Button1: TButton Left = 32 Top = 16 ... end object Button2: TButton Left = 32 Top = 56 ... end object Button3: TButton Left = 32 Top = 96 ... end end = =
141.
What We CanDo in Streaming Process ? Override TPersistent.DefineProperties method to store unpublished data. Call TFiler.DefineProperty for ordinal values. Call TFiler.DefineBinaryProperty for binary data. For example: Left & Top properties of non-visual components Contents of TStrings objects Contents of TCollection objects Images of TGraphic objects
142.
Additional Data inStream object Form1: TForm1 ... object Timer1: TTimer Left = 264 Top = 176 end object Memo1: TMemo ... Lines.Strings = ( 'Memo1' 'Line 2' 'Line 3') end object StatusBar1: TStatusBar ... Panels = < item Width = 50 end item Bevel = pbRaised Width = 50 end item Width = 50 end> end end
143.
Overrided TComponent.DefineProperties procedureTComponent.ReadLeft(Reader: TReader); begin LongRec(FDesignInfo).Lo := Reader. ReadInteger ; end; procedure TComponent.ReadTop(Reader: TReader); begin LongRec(FDesignInfo).Hi := Reader. ReadInteger ; end; procedure TComponent.WriteLeft(Writer: TWriter); begin Writer. WriteInteger (LongRec(FDesignInfo).Lo); end; procedure TComponent.WriteTop(Writer: TWriter); begin Writer. WriteInteger (LongRec(FDesignInfo).Hi); end; procedure TComponent.DefineProperties(Filer: TFiler); var Ancestor: TComponent; Info: Longint; begin Info := 0; Ancestor := TComponent(Filer.Ancestor); if Ancestor <> nil then Info := Ancestor.FDesignInfo; Filer. DefineProperty ('Left', ReadLeft, WriteLeft, LongRec(FDesignInfo).Lo <> LongRec(Info).Lo); Filer. DefineProperty ('Top', ReadTop, WriteTop, LongRec(FDesignInfo).Hi <> LongRec(Info).Hi); end;
144.
Overrided TStrings.DefineProperties procedureTStrings.ReadData(Reader: TReader); begin Reader. ReadListBegin ; BeginUpdate; try Clear; while not Reader. EndOfList do Add(Reader. ReadString ); finally EndUpdate; end; Reader. ReadListEnd ; end; procedure TStrings.WriteData(Writer: TWriter); var I: Integer; begin Writer. WriteListBegin ; for I := 0 to Count - 1 do Writer. WriteString (Get(I)); Writer. WriteListEnd ; end; procedure TStrings.DefineProperties(Filer: TFiler); function DoWrite: Boolean; begin if Filer.Ancestor <> nil then begin Result := True; if Filer.Ancestor is TStrings then Result := not Equals(TStrings(Filer.Ancestor)) end else Result := Count > 0; end; begin Filer. DefineProperty ('Strings', ReadData, WriteData, DoWrite); end;
145.
Streaming on DailyBasis Eliminate manual persistence support for objects and components DO NOT re-invent the wheels Use TReader and TWriter to support stream handling Let TReader and TWriter to take care storage size and exceptions Manipulate forms inside executables Read form data of other’s program You can even create instance of other’s form
146.
Other Topics onStreaming Converting Between Binary and Text ObjectResourceToText ObjectBinaryToText ObjectTextToResource ObjectTextToBinary Convert.exe which is under \Delphi\Bin directory Default value Never distinguish with initial value of object TComponent = class(TPersistent) published property Name: TComponentName read FName write SetName stored False; property Tag: Longint read FTag write FTag default 0 ; end;
147.
Messaging Messages arethe components’ ONLY connection to the outside world. Component developers generally write numerous message handlers for components. Only after understanding message routing, you really understand Windows Programming.
Other Topics onWindow and Messaging TControl.Perform method TWinControl.Broadcast method Allocate window handle for windowless component AllocateHWnd and DeallocateHwnd Component messages Designed for windowless components Delphi 5 has 69 CM_XXX messages and 24 CN_XXX notification messages WM_KEYDOWN => CN_KEYDOWN
151.
Summary The moreunderstanding of VCL innerworks, the less difficulties while writing component Unmentioned interesting topics Other VCL subsystems Assign and AssignTo Free Notification Thread Synchronization Packages Property editors, component editors OpenTools API
檢視 DLL 提供的函式 E:\WINNT\system32>dumpbin /exports user32.dll Microsoft (R) COFF Binary File Dumper Version 5.00.7022 Copyright (C) Microsoft Corp 1992-1997. All rights reserved. Dump of file user32.dll File Type: DLL Section contains the following Exports for USER32.dll 0 characteristics 336A2A2A time date stamp Sat May 03 01:53:46 1997 0.00 version 1 ordinal base 634 number of functions 634 number of names ordinal hint name 1 0 ActivateKeyboardLayout (00015B1A) 2 1 AdjustWindowRect (0000D704) 3 2 AdjustWindowRectEx (00007D8E) 4 3 AnyPopup (00043ABB) 5 4 AppendMenuA (00011F57) 6 5 AppendMenuW (0002D7A4)
Outlines Why COM? Component Interface IUnknown Interface and QueryInterface Reference Counting Class and Interface Locating Techniques based on COM Conclusions
183.
Why COM ?The dream of “Software IC” We need an object model which supports the following features Language independent Dynamic binding Encapsulation Version control Distributed computing ...
184.
Component A dream:All applications are built on components without much programming task After software upgrade: single software component software Comp A Comp B Comp C Comp D Comp E component software Comp A Comp B Comp C Comp D New version of Comp E
185.
Advantages of UsingComponent Customizing capability Rapid and easy application development Application partition cross different hosts component software Proxy of Comp A Comp B Proxy of Comp C component providers Comp A network Comp C
186.
Object Model RequirementsDynamic Binding Encapsulation Hide language features – language indepenedent Binary format Feeling less upgrade Network transparency
187.
COM Specification COM(Component Object Model) is just a specification COM object is ... Existed in DLLs or EXEs Language indepenedent (either component design or use) Existed as binary format Feeling less upgrade Network transparency (Distributed COM)
188.
COM IS NOT... COM is not a programming language COM is not an competitor of DLLs COM object exists in DLLs COM is not a set of API COM implementers would publish a set of API functions to COM programmers COM is not a class library or framework There are only few interfaces designated in COM specifications
189.
Interface What isinterface ? “ Pure” interface Operations only, no storages Fully detached from class implementation Comparsion with class declaration in C++ Why interface ? Fully independent with implementation, therefore we can break away from language spec. & development tool implementation
190.
Interface (cont) Interfacesnever change !! (For version control) Polymorphism Interface inheritance v.s. implementation inheritance One object usually supports multiple interfaces Simple interface is better
191.
QueryInterface Ultimate interface– IUnknown Three operations of IUnknown interface AddRef Release Interface All objects at least support IUnknown interface There are no way to enumerate all interfaces supported by one object Why COM does not support interface enumeration ?
192.
Reference Counting Objectusers only obtain interfaces, no one could obtain objects Object must maintain reference counter to make lifetime control Object reference counting v.s. Interface reference counting Resource managment
193.
Class and InterfaceNaming COM make use of GUID (Globally Unique IDentifier) GUID is developed by OSF (Open Software Foundation) for DCE (Distributed Computing Environment) RPC (Remote Procedure Call) GUID is 128 bit integer GUID is confirmed to be unique in time and space (It will be altered every 100 nanoseconds) We call GUID of class “CLSID”, GUID of interfaces “IID” Windows stores CLSID, IID in system registry
例外處理機制 傳統錯誤判斷方法: Dirty,inconvenient and easily generate mistakes. GetMem(pBuffer, 1000); if (pBuffer = nil) then begin /* error processing code here; */ end; // 取得 x, 計算 x 的倒數 if x = 0 then begin /* error processing code here; */ end;
199.
例外處理機制 例外處理方式: 讓例外狀況的處理動作不影響正常流程。try edtTotal.Text := IntToStr( StrToInt( edtOp1.Text ) / StrToInt( edtOp2.Text ) ); except on EDivByZero do ShowMessage( ' Cannot divide by zero ' ); on EConvertError do ShowMessage( ' Error during conversion ' ); end;
200.
例外處理機制 主動丟出例外: 將例外狀況集中處理。try if numItems = 0 then raise EDivByZero.Create( ' Cannot divide by zero ' ) // ^ throw your own exception else edtAvg.Text := FloatToStr( sum / numItems ); except edtAvg.Text := FloatToStr(0.0); raise; // <- re-throw the same exception end;
參考書目 - C / C++ Programming The C Programming Language Brian W. Kernighan / Prentice Hall The C++ Programming Language Bjarne Stroustrup / Addison Wesley C++ 程式語言經典本 / 葉秉哲 / 儒林 C++ Primer Stanley B. Lippman, Josee Lajoie, Jose Lajoie / Prentice Hall C++ Primer 中文版 / 侯捷 / 碁峰
217.
參考書目- Delphi/ C++Builder Delphi 學習筆記 Win32 基礎篇 錢達智 / 碁峰 Delphi 深度歷險 陳寬達 / 碁峰 Secrets of Delphi 2 Ray Lischner / Waite Group Delphi Component Design Danny Thorpe / Addison Wesley C++Builder 4 Unleashed Charlie Calvert / SAMS
218.
參考書目 - Windows Programming Programming Windows Charles Petzold / Microsoft Press Programming Applications for Microsoft Windows Jeffrey Richter / Microsoft Press Windows 95: A Developer’s Guide Jeffrey Richter, Jonathan Locke / M&T Books Windows 95 程式設計指南 / 李書良譯 / 碁峰 Multithreading Applications in Win32 James Beveridge, Robert Wiener / Addison Wesley Win32 多緒程式設計 / 侯俊傑譯 / 碁峰
219.
參考書目- OOA/ OOD / OOP Object-Oriented Analysis and Design with Applications, 2 nd Ed. Grady Booch / Benjamin/Cummings Publishing Object-Oriented Modeling And Design James Rumbaugh, etc. / Prentice Hall Object-Oriented Software Construction 2 nd Ed. Bertrand Meyer / Prentice Hall Design Patterns, Elements of Reusable Object-Oriented Software GoF / Addiseon Wesley 物件導向設計模式 / 葉秉哲 / 培生
220.
參考書目- PracticalProgramming Programming Pearls 2 nd Ed. Jon Bentley / Addiseon Wesley The Practice of Programming Brian W.Kernighan, Rob Pike / Addiseon Wesley Write Solid Code Steve Maguire / Microsoft Press 如何撰寫0錯誤程式 / 施威銘研究室 / 旗標
221.
參考書目- 工具書Win32 Programming Brent Rector, Joseph Newcomer / Addison Wesley Delphi Programming Problem Solver Neil Rubenking / IDG Books Delphi 2 高階技巧 / 劉剛樑譯