前言
今天的Windows應(yīng)用開發(fā)課上缭裆,教授讓我們用純C語言實現(xiàn)面向?qū)ο蟮拈_發(fā)和封裝键闺。如果用C++那實現(xiàn)面向?qū)ο笫禽p而易舉,但是用純C的話澈驼,emmm想想就頭大辛燥,光一個字符串的操作就搞了半天,和C++比起來缝其,C語言真的太“基礎(chǔ)”了挎塌,幾乎所有的方法都要自己寫。
這個代碼我硬鋼了兩天内边,一共寫了500行左右榴都,收獲還是蠻大的,算是比較完善的將方法封裝了起來漠其。
代碼要求
- 用純C實現(xiàn)面向?qū)ο缶幊?/li>
- 包含基類和一層子類嘴高,子類及其繼承的方法由用戶自己設(shè)定,但要有接口
- 所有的方法都要進行封裝和屎,不能顯示出來參數(shù)類型
代碼實現(xiàn)結(jié)構(gòu)
首先拴驮,為了實現(xiàn)封裝而且不顯示參數(shù)類型,將所有的參數(shù)都設(shè)置為int類型(包括結(jié)構(gòu)體)柴信,通過int轉(zhuǎn)換為各種指針類型套啤,再由指針析取為實際類型進行參數(shù)的操作。
所有的方法封裝到WinProc
接口中颠印,通過其中的msg
參數(shù)辨別進行哪一個方法的調(diào)用纲岭。另外,為了實現(xiàn)基類和子類接口的統(tǒng)一线罕,另外加了一個CallProc
接口止潮,實現(xiàn)分配基類和子類的操作函數(shù)。
//封裝的窗口操作函數(shù)
int WinProc(int win, int msg, int param1, int param2) {
switch (msg){
case MOVE: move(win, param1, param2); break;
case SET_POSITION: SetPosition(win, param1, param2); break;
case GET_POSITION: {Pos p = GetPosition(win); return (int)&p; }break;
case SET_SIZE: SetSize(win, param1, param2); break;
case GET_SIZE: {WinSize p = GetSize(win); return (int)&p; }break;
case SET_TITLE: SetTitle(win, (char*)param1); break;
case GET_TITLE: return (int)GetTitle(win); break;
case PRINTWINDOW: PrintWindow(win); break;
case CONSTRUCT: return ConstructBase(win); break;
case DESTRACT: DestroyWindow(win); break;
case MEM_GET: return getMem(win, param1); break;
case MEM_SET: setMem(win, param1, param2); break;
case STATIC_GET: return getStatic(win, param1, param2); break;
case STATIC_SET: setStatic(win, param1, param2); break;
case COPY: return CopyWindow(win); break;
default: break;
}
}
//分配基類和子類操作函數(shù)的調(diào)用接口
int CallProc(int win, int msg, int param1, int param2) {
for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
if (objects[i].object == win) { //找到這個實例
if (objects[i].index == -1) //如果是基類钞楼,則返回基類對應(yīng)的操作函數(shù)
return WinProc(win, msg, param1, param2);
return subclasses[objects[i].index].pFn(win, msg, param1, param2); //如果是子類喇闸,則返回子類對應(yīng)的操作函數(shù)
}
}
return 0;
}
該項目建立了一個基類為window
,其中包括一組窗口的位置信息Pos
包含x
和y
询件,和窗口的大小信息WinSize
包含width
和height
燃乍,還有窗口的名字title
,是一個 char[200]
數(shù)組(懷念C++的string啊~~~~)
//位置結(jié)構(gòu)體宛琅,包含(x刻蟹,y)
typedef struct Pos {
int x, y;
};
//窗口大小結(jié)構(gòu)體,包含寬嘿辟、高
typedef struct WinSize {
int width, height;
};
//基類
struct window {
Pos pos;
WinSize size;
char title[200];
};
在這個基類的基礎(chǔ)上舆瘪,用戶可以通過RegisterClass()
接口創(chuàng)建子類,子類可以包含附加變量和static變量红伦,在創(chuàng)建時要說明變量類型(即變量所占用字節(jié)數(shù))用于后期分配內(nèi)存英古。
//創(chuàng)建一個新的子類
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int)) {
strcpy(subclasses[subClassIndex].Name, name);
subclasses[subClassIndex].Bytes = data;
subclasses[subClassIndex].StaticBytes = staticdata;
subclasses[subClassIndex].pStatic = (char*)malloc(staticdata); //開辟子類的static內(nèi)存空間
subclasses[subClassIndex].pFn = fn;
//初始化靜態(tài)變量
int type;
switch (staticdata) {
case 4: *(int*)subclasses[subClassIndex].pStatic = 0; break; //int初始化為0
case 1: *(char*)subclasses[subClassIndex].pStatic = 'a'; break; //char初始化為‘a(chǎn)’
default:strcpy(subclasses[subClassIndex].pStatic, ""); break; //string初始化為空串
}
subClassIndex++; //子類的個數(shù)增加1
}
為了儲存子類和實例,分別又建立了兩個結(jié)構(gòu)體SubClass
和Object
昙读,并分別開辟了兩個數(shù)組來儲存子類和實例召调。SubClass
結(jié)構(gòu)體中包含了子類的名字、子類附加變量增加字節(jié)數(shù)蛮浑、子類static變量增加字節(jié)數(shù)唠叛、指向static變量的指針和一個函數(shù)指針(這里類似C++中函數(shù)的重載)。Object
結(jié)構(gòu)體中儲存了類的實例沮稚,其中包含了指向類的實例的指針和一個表示子類類型的指針玻墅。
//子類
struct SubClass {
char Name[200]; //子類名字
int Bytes; //子類附加變量增加字節(jié)數(shù)
int StaticBytes; //子類static變量增加字節(jié)數(shù)
char* pStatic; //子類static的指針
int (*pFn)(int win, int msg, int param1, int param2); //子類的方法函數(shù)
}subclasses[50];
int subClassIndex = 0;
//獲取當前創(chuàng)建的子類總數(shù)
int getSubClassNum() { return subClassIndex; }
//所有類的實例
struct Object {
int object; //類的實例
int index; //若為基類的實例則是-1,若為子類的實例則為其在subclasses里面對應(yīng)子類的下標
}objects[100];
int objectIndex = 0; //實例的個數(shù)
//獲取當前創(chuàng)建的實例總數(shù)
int getObjNum() { return objectIndex; }
關(guān)鍵細節(jié)
-
void* p = malloc(sizeof(window) + subclasses[objects[i].index].Bytes);
開辟子類實例的內(nèi)存空間壮虫。子類實例不僅要開辟基類變量所包含的內(nèi)存空間(實現(xiàn)繼承)澳厢,還要有自己的內(nèi)存空間∏羲疲【注意:子類的實例不包含子類變量的static靜態(tài)變量的內(nèi)存空間剩拢。因為靜態(tài)變量是屬于子類的,在定義子類的時候已經(jīng)開辟饶唤,不屬于子類的實例徐伐。】 -
window* p = (window*)win;
因為在項目中所有的參數(shù)傳遞都是用指針以int類型進行傳遞募狂,這個語句可以將int(實際上是指針)轉(zhuǎn)換為window類型办素。其他類型的轉(zhuǎn)換同理角雷。 -
char* p = (char*)win + sizeof(window);
這一步操作本質(zhì)上只是一個指針的跨越,但是它實現(xiàn)了對子類附加變量的指針定位性穿。
不足之處
代碼中有一個暫未解決的bug勺三,本來說是想實現(xiàn)構(gòu)造函數(shù)和析構(gòu)函數(shù),但在 delete 清除實例內(nèi)存的時候出現(xiàn)了一點問題需曾,總是報內(nèi)存泄漏的錯誤吗坚,希望路過的大佬可以幫忙完善一下,不盡感激呆万。
//刪除窗口(暫未通過調(diào)試)
void DestroyWindow(int win) {
if (!win) {
delete (window*)win;
}
}
完整代碼
完整的window.cpp如下:
//Author:SongXingJian
#include "stdio.h"
#include "string.h"
#include "malloc.h"
#include "window.h"
//位置結(jié)構(gòu)體商源,包含(x,y)
typedef struct Pos {
int x, y;
};
//窗口大小結(jié)構(gòu)體谋减,包含寬牡彻、高
typedef struct WinSize {
int width, height;
};
//基類
struct window {
Pos pos;
WinSize size;
char title[200];
};
//子類
struct SubClass {
char Name[200]; //子類名字
int Bytes; //子類附加變量增加字節(jié)數(shù)
int StaticBytes; //子類static變量增加字節(jié)數(shù)
char* pStatic; //子類static的指針
int (*pFn)(int win, int msg, int param1, int param2); //子類的方法函數(shù)
}subclasses[50];
int subClassIndex = 0;
//獲取當前創(chuàng)建的子類總數(shù)
int getSubClassNum() { return subClassIndex; }
//所有類的實例
struct Object {
int object; //類的實例
int index; //若為基類的實例則是-1,若為子類的實例則為其在subclasses里面對應(yīng)子類的下標
}objects[100];
int objectIndex = 0; //實例的個數(shù)
//獲取當前創(chuàng)建的實例總數(shù)
int getObjNum() { return objectIndex; }
//創(chuàng)建一個新的子類
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int)) {
strcpy(subclasses[subClassIndex].Name, name);
subclasses[subClassIndex].Bytes = data;
subclasses[subClassIndex].StaticBytes = staticdata;
subclasses[subClassIndex].pStatic = (char*)malloc(staticdata); //開辟子類的static內(nèi)存空間
subclasses[subClassIndex].pFn = fn;
//初始化靜態(tài)變量
int type;
switch (staticdata) {
case 4: *(int*)subclasses[subClassIndex].pStatic = 0; break; //int初始化為0
case 1: *(char*)subclasses[subClassIndex].pStatic = 'a'; break; //char初始化為‘a(chǎn)’
default:strcpy(subclasses[subClassIndex].pStatic, ""); break; //string初始化為空串
}
subClassIndex++; //子類的個數(shù)增加1
}
//移動窗口
void move(int win, int deltaX, int deltaY) {
window* p = (window*)win; //將任意封裝類型強制轉(zhuǎn)化為所需要的內(nèi)容
p->pos.x += deltaX;
p->pos.y += deltaY;
}
//設(shè)置窗口位置
void SetPosition(int win, int x, int y) {
window* p = (window*)win;
p->pos.x = x;
p->pos.y = y;
}
//返回窗口位置
Pos GetPosition(int win) {
window* p = (window*)win;
Pos win_pos;
win_pos.x = p->pos.x;
win_pos.y = p->pos.y;
return win_pos;
}
//設(shè)置窗口寬和高
void SetSize(int win, int width, int height) {
window* p = (window*)win;
p->size.width = width;
p->size.height = height;
}
//獲取窗口寬和高
WinSize GetSize(int win) {
window* p = (window*)win;
WinSize win_size;
win_size.width = p->size.width;
win_size.height = p->size.height;
return win_size;
}
//設(shè)置窗口title
void SetTitle(int win, char* newTitle) {
window* p = (window*)win;
//p->title = newTitle;
strcpy(p->title, newTitle);
}
//返回窗口title
char* GetTitle(int win) {
window* p = (window*)win;
return p->title;
}
//創(chuàng)建Window出爹,參數(shù)是子類名字讨便,創(chuàng)建基類則傳入0
int CreateWindow(char* name) {
int new_win = 0;
if (!name) { //創(chuàng)建基類實例
window* p = (window*)malloc(sizeof(window));
WinProc((int)p, CONSTRUCT, 0, 0); //初始化基類變量
new_win = (int)p;
objects[objectIndex].object = new_win;
objects[objectIndex].index = -1; //基類的下標設(shè)置為-1
objectIndex++; //實例數(shù)+1
}
else { //創(chuàng)建子類實例
for (int j = 0; j < subClassIndex; ++j) {
if (!strcmp(name, subclasses[j].Name)) { //如果name相等,即找到了subclasses的位置
void* p = malloc(sizeof(window) + subclasses[j].Bytes); //開辟該子類實例所需空間
WinProc((int)p, CONSTRUCT, 0, 0); //初始化基類變量
new_win = (int)p;
objects[objectIndex].object = new_win;
objects[objectIndex].index = j; //下標設(shè)置為在subclasses里面相同子類的下標
objectIndex++; //實例數(shù)+1
break;
}
}
}
return new_win;
}
//基類的構(gòu)造函數(shù),初始化基類變量
int ConstructBase(int win) {
window* p = (window*)win;
strcpy(p->title, "");
p->pos.x = 0;
p->pos.y = 0;
p->size.width = 0;
p->size.height = 0;
return (int)p;
}
//拷貝并創(chuàng)建實例
int CopyWindow(int win) {
int new_win;
for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
if (objects[i].object == win) { //找到這個實例
if (objects[i].index != -1) { //如果是子類
void* p = malloc(sizeof(window) + subclasses[objects[i].index].Bytes); //開辟該子類實例所需空間
new_win = (int)p;
WinProc(new_win, CONSTRUCT, 0, 0);
//確定子類附加變量的參數(shù)類型
int type_mem;
if (subclasses[objects[i].index].Bytes == 4) type_mem = SUB_INT;
else if (subclasses[objects[i].index].Bytes == 1) type_mem = SUB_CHAR;
else type_mem = SUB_STRING;
//復(fù)制子類附加變量
WinProc(new_win, MEM_SET, type_mem, WinProc(objects[i].object, MEM_GET, type_mem, 0));
objects[objectIndex].object = new_win;
objects[objectIndex].index = objects[i].index; //下標設(shè)置為在subclasses里面相同子類的下標
objectIndex++; //實例數(shù)+1
}
else { //如果是基類
window* p = (window*)malloc(sizeof(window));
new_win = (int)p;
WinProc(new_win, CONSTRUCT, 0, 0);
objects[objectIndex].object = new_win;
objects[objectIndex].index = -1; //基類的下標設(shè)置為-1
objectIndex++; //實例數(shù)+1
}
//復(fù)制基類變量
WinProc(new_win, SET_TITLE, WinProc(objects[i].object, GET_TITLE, 0, 0), 0); //賦值新實例的title
Pos w_pos = *(Pos*)WinProc(objects[i].object, GET_POSITION, 0, 0); //獲取被復(fù)制實例的pos
WinProc(new_win, SET_POSITION, w_pos.x, w_pos.y); //賦值新實例的pos
WinSize w_size = *(WinSize*)WinProc(objects[i].object, GET_SIZE, 0, 0); //獲取被復(fù)制實例的size
WinProc(new_win, SET_SIZE, w_size.width, w_size.height); //賦值新實例的size
return new_win;
}
}
}
//刪除窗口(暫未通過調(diào)試)
void DestroyWindow(int win) {
if (!win) {
delete (window*)win;
}
}
//打印窗口的所有屬性
void PrintWindow(int win) {
window* p = (window*)win;
printf_s("\n================ %s ================\nPosition: (%d, %d)\nWidth: %d\tHeight: %d\n", p->title, p->pos.x, p->pos.y, p->size.width, p->size.height);
}
//獲得子類中的變量
int getMem(int win, int sub_type) {
char* p = (char*)win + sizeof(window); //指針p跨越基類內(nèi)存以政,指向子類附加內(nèi)存
if (sub_type == SUB_INT) //子類附加的數(shù)據(jù)是int
return *(int*)p;
else if (sub_type == SUB_CHAR) //子類附加的數(shù)據(jù)是char
return *p;
else if (sub_type == SUB_STRING) //子類附加的數(shù)據(jù)是字符串
return (int)p;
}
//設(shè)置子類中的變量
void setMem(int win, int sub_type, int param2) {
char* p = (char*)win + sizeof(window); //指針p跨越基類內(nèi)存霸褒,指向子類附加內(nèi)存
if (sub_type == SUB_INT) //子類附加的數(shù)據(jù)是int
*(int*)p = param2;
else if (sub_type == SUB_CHAR) //子類附加的數(shù)據(jù)是char
*p = param2;
else if (sub_type == SUB_STRING) //子類附加的數(shù)據(jù)是字符串
strcpy(p, (char*)param2);
}
//獲得子類中的static變量
int getStatic(int win, int sub_type, int param2) {
char* p = 0;
for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
if (objects[i].object == win) { //找到這個實例
if (objects[i].index != -1) //如果不是基類
p = subclasses[objects[i].index].pStatic;
break;
}
}
if (sub_type == SUB_INT) //子類static變量是int
return *(int*)p;
else if (sub_type == SUB_CHAR) //子類static變量是char
return *p;
else if (sub_type == SUB_STRING) //子類static變量是字符串
return (int)p;
}
//設(shè)置子類的static變量
void setStatic(int win, int sub_type, int param2) {
char* p = 0;
for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
if (objects[i].object == win) { //找到這個實例對應(yīng)的子類
if (objects[i].index != -1) {
p = subclasses[objects[i].index].pStatic;
if (sub_type == SUB_INT)
*(int*)p = param2;
else if (sub_type == SUB_CHAR)
*p = param2;
else if (sub_type == SUB_STRING)
strcpy(p, (char*)param2);
break;
}
}
}
}
//封裝的窗口操作函數(shù)
int WinProc(int win, int msg, int param1, int param2) {
switch (msg){
case MOVE: move(win, param1, param2); break;
case SET_POSITION: SetPosition(win, param1, param2); break;
case GET_POSITION: {Pos p = GetPosition(win); return (int)&p; }break;
case SET_SIZE: SetSize(win, param1, param2); break;
case GET_SIZE: {WinSize p = GetSize(win); return (int)&p; }break;
case SET_TITLE: SetTitle(win, (char*)param1); break;
case GET_TITLE: return (int)GetTitle(win); break;
case PRINTWINDOW: PrintWindow(win); break;
case CONSTRUCT: return ConstructBase(win); break;
case DESTRACT: DestroyWindow(win); break;
case MEM_GET: return getMem(win, param1); break;
case MEM_SET: setMem(win, param1, param2); break;
case STATIC_GET: return getStatic(win, param1, param2); break;
case STATIC_SET: setStatic(win, param1, param2); break;
case COPY: return CopyWindow(win); break;
default: break;
}
}
//分配基類和子類操作函數(shù)的調(diào)用接口
int CallProc(int win, int msg, int param1, int param2) {
for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
if (objects[i].object == win) { //找到這個實例
if (objects[i].index == -1) //如果是基類,則返回基類對應(yīng)的操作函數(shù)
return WinProc(win, msg, param1, param2);
return subclasses[objects[i].index].pFn(win, msg, param1, param2); //如果是子類盈蛮,則返回子類對應(yīng)的操作函數(shù)
}
}
return 0;
}
完整的window.h如下:
//Author:SongXingJian
#define MOVE 1
#define SET_POSITION 2
#define GET_POSITION 3
#define SET_SIZE 4
#define GET_SIZE 5
#define SET_TITLE 6
#define GET_TITLE 7
#define PRINTWINDOW 8
#define CONSTRUCT 9
#define DESTRACT 10 //暫未通過調(diào)試
#define MEM_GET 11
#define MEM_SET 12
#define STATIC_GET 13
#define STATIC_SET 14
#define SUB_INT 15
#define SUB_CHAR 16
#define SUB_STRING 17
#define COPY 18
int getSubClassNum(); //獲取當前創(chuàng)建的子類總數(shù)
int getObjNum(); //獲取當前創(chuàng)建的實例總數(shù)
int CreateWindow(char* name); //創(chuàng)建實例废菱,參數(shù)是子類名字,基類則傳入0
int WinProc(int win, int msg, int param1, int param2); //SDK整體封裝
int CallProc(int win, int msg, int param1, int param2); //多態(tài)
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int)); //定義一個新的子類
/* 封裝過程
//void move(window* win, int deltaX, int deltaY);
//void move(void* win, int deltaX, int deltaY);
void move(int win, int deltaX, int deltaY); //對外提供接口
struct Pos GetPosition(int win);
void Size(int win, int newX, int newY);
void SetWindowText(int win, char* newTitle);
char* GetWindowText(int win);
*/
完整的main_test.cpp(主函數(shù))如下:
//Author:SongXingJian
#include "window.h"
#include "stdio.h"
//win_num子類的函數(shù)
int sub_window_num(int win, int msg, int param1, int param2) {
switch (msg){
//子類構(gòu)造函數(shù)抖誉,創(chuàng)建一個子類
case CONSTRUCT: {
int w = CreateWindow((char*)win);
WinProc(w, SET_TITLE, param1, 0); //初始化title
WinProc(w, MEM_SET, SUB_INT, 0); //初始化子類實例附加變量為0
return w;
}break;
//設(shè)置子類實例附加變量
case MEM_SET: {
printf("Set the num: %d ---> %d\n", WinProc(win, MEM_GET, SUB_INT, 0), param2); //展示修改前--->修改后
WinProc(win, msg, SUB_INT, param2);
}break;
//獲取子類實例附加變量
case MEM_GET: {
int p = WinProc(win, msg, SUB_INT, 0);
printf("Num: %d\n", p);
}break;
//設(shè)置子類static變量
case STATIC_SET: {
printf("Set the static: %d ---> %d\n", WinProc(win, STATIC_GET, SUB_INT, 0), param2); //展示修改前--->修改后
WinProc(win, msg, SUB_INT, param2);
}break;
//獲取子類static變量
case STATIC_GET: {
int p = WinProc(win, msg, SUB_INT, 0);
printf("Static: %d\n", p);
}break;
//打印子類實例的所有變量
case PRINTWINDOW: {
WinProc(win, msg, param1, param2);
printf("Num: %d\t\tStatic: %d\n", WinProc(win, MEM_GET, SUB_INT, 0), WinProc(win, STATIC_GET, SUB_INT, 0));
}break;
default:return WinProc(win, msg, param1, param2); break;
}
}
//win_c子類的函數(shù)
int sub_window_c(int win, int msg, int param1, int param2) {
switch (msg) {
//子類構(gòu)造函數(shù)殊轴,創(chuàng)建一個子類
case CONSTRUCT: {
int w = CreateWindow((char*)win);
WinProc(w, SET_TITLE, param1, 0); //初始化title
WinProc(w, MEM_SET, SUB_CHAR, (int)'A'); //初始化子類實例附加變量為'A'
return w;
}break;
//設(shè)置子類實例附加變量
case MEM_SET: {
printf("Set the Char: %c ---> %c\n", WinProc(win, MEM_GET, SUB_CHAR, 0), (char)param2); //展示修改前--->修改后
WinProc(win, msg, SUB_CHAR, param2);
}break;
//獲取子類實例附加變量
case MEM_GET: {
int p = WinProc(win, msg, SUB_CHAR, 0);
printf("Char: %c\n", (char)p);
}break;
//設(shè)置子類static變量
case STATIC_SET: {
printf("Set the static: %c ---> %c\n", (char)WinProc(win, STATIC_GET, SUB_CHAR, 0), (char)param2); //展示修改前--->修改后
WinProc(win, msg, SUB_CHAR, param2);
}break;
//獲取子類static變量
case STATIC_GET: {
int p = WinProc(win, msg, SUB_CHAR, 0);
printf("Static: %c\n", (char)p);
}break;
//打印子類實例的所有變量
case PRINTWINDOW: {
WinProc(win, msg, param1, param2);
printf("Char: %c\t\tStatic: %c\n", WinProc(win, MEM_GET, SUB_CHAR, 0), WinProc(win, STATIC_GET, SUB_CHAR, 0));
}break;
default:return WinProc(win, msg, param1, param2); break;
}
}
int main() {
char win_num[] = "sub_win_num";
char win_c[] = "sub_win_c";
char win_num_obj[] = "sub_win_num_obj";
char win_c_obj[] = "sub_win_c_obj";
char win_base_obj[] = "base_win_obj";
/****************** 創(chuàng)建win_num子類 ******************/
RegisterClass(win_num, sizeof(int), sizeof(int), sub_window_num);
//int sub_w = CreateWindow(win_num);
int sub_w = sub_window_num((int)win_num, CONSTRUCT, (int)win_num_obj, 0); // 構(gòu)造函數(shù),可以創(chuàng)建實例袒炉,并初始化title旁理、基類變量和實例附加變量
CallProc(sub_w, MEM_SET, SUB_INT, 5); //設(shè)置實例的子類附加變量
CallProc(sub_w, MEM_GET, SUB_INT, 0);
CallProc(sub_w, STATIC_SET, SUB_INT, 3); //設(shè)置實例所屬子類static變量
CallProc(sub_w, STATIC_GET, SUB_INT, 0);
CallProc(sub_w, PRINTWINDOW, 0, 0); //打印窗口屬性
//復(fù)制這個實例
int sub_w_copy = CallProc(sub_w, COPY, 0, 0);
CallProc(sub_w_copy, PRINTWINDOW, 0, 0); //打印窗口屬性
//驗證子類static變量的性質(zhì)
printf("\n\n****** 驗證子類static變量的性質(zhì) ******\n");
CallProc(sub_w_copy, STATIC_SET, SUB_INT, 100); //通過復(fù)制的實例修改靜態(tài)變量
CallProc(sub_w, STATIC_GET, SUB_INT, 0); //通過另一個實例調(diào)用
printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());
/****************** 創(chuàng)建win_c子類 ******************/
RegisterClass(win_c, sizeof(char), sizeof(char), sub_window_c);
int sub_w_c = sub_window_c((int)win_c, CONSTRUCT, (int)win_c_obj, 0); // 構(gòu)造函數(shù),可以創(chuàng)建實例我磁,并初始化title孽文、基類變量和實例附加變量
CallProc(sub_w_c, MEM_SET, SUB_CHAR, (int)'B'); //設(shè)置實例的子類附加變量
CallProc(sub_w_c, MEM_GET, SUB_CHAR, 0);
CallProc(sub_w_c, STATIC_SET, SUB_CHAR, (int)'S'); //設(shè)置實例所屬子類static變量
CallProc(sub_w_c, STATIC_GET, SUB_CHAR, 0);
CallProc(sub_w_c, PRINTWINDOW, 0, 0); //打印窗口屬性
//復(fù)制這個實例
int sub_w_c_copy = CallProc(sub_w_c, COPY, 0, 0);
CallProc(sub_w_c_copy, PRINTWINDOW, 0, 0);
printf("\n\n****** The total number of Objects: %d ******\n\n", getObjNum());
printf("\n****** The total number of SubClasses: %d ******\n\n", getSubClassNum());
/****************** 創(chuàng)建基類 ******************/
int base_w = CreateWindow(0);
CallProc(base_w, PRINTWINDOW, 0, 0); //打印初始化的基類
CallProc(base_w, SET_TITLE, (int)win_base_obj, 0); //窗口重命名
CallProc(base_w, SET_POSITION, 3, 4); //設(shè)置窗口位置
CallProc(base_w, MOVE, 2, 2); //移動窗口
CallProc(base_w, SET_SIZE, 5, 5); //設(shè)置窗口大小
CallProc(base_w, PRINTWINDOW, 0, 0); //打印窗口屬性
printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());
return 0;
}