C語言實現面向對象和封裝

前言

今天的Windows應用開發課上,教授讓我們用純C語言實現面向對象的開發和封裝。如果用C++那實現面向對象是輕而易舉,但是用純C的話,emmm想想就頭大,光一個字符串的操作就搞了半天,和C++比起來,C語言真的太“基礎”了,幾乎所有的方法都要自己寫。
這個代碼我硬鋼了兩天,一共寫了500行左右,收穫還是蠻大的,算是比較完善的將方法封裝了起來。

代碼要求

  • 用純C實現面向對象編程
  • 包含基類和一層子類,子類及其繼承的方法由用戶自己設定,但要有接口
  • 所有的方法都要進行封裝,不能顯示出來參數類型

代碼實現結構

首先,爲了實現封裝而且不顯示參數類型,將所有的參數都設置爲int類型(包括結構體),通過int轉換爲各種指針類型,再由指針析取爲實際類型進行參數的操作

所有的方法封裝到WinProc接口中,通過其中的msg參數辨別進行哪一個方法的調用。另外,爲了實現基類和子類接口的統一,另外加了一個CallProc接口,實現分配基類和子類的操作函數。

//封裝的窗口操作函數
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;
	}
}

//分配基類和子類操作函數的調用接口
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)		//如果是基類,則返回基類對應的操作函數
				return WinProc(win, msg, param1, param2);
			return subclasses[objects[i].index].pFn(win, msg, param1, param2);	//如果是子類,則返回子類對應的操作函數
		}
	}
	return 0;
}

該項目建立了一個基類window,其中包括一組窗口的位置信息Pos包含xy,和窗口的大小信息WinSize包含widthheight,還有窗口的名字title,是一個 char[200] 數組(懷念C++的string啊~~~~)

//位置結構體,包含(x,y)
typedef struct Pos {	
	int x, y;
};

//窗口大小結構體,包含寬、高
typedef struct WinSize {	
	int width, height;
};

//基類
struct window {
	Pos pos;
	WinSize size;
	char title[200];
};

在這個基類的基礎上,用戶可以通過RegisterClass()接口創建子類,子類可以包含附加變量和static變量,在創建時要說明變量類型(即變量所佔用字節數)用於後期分配內存。

//創建一個新的子類
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內存空間
	subclasses[subClassIndex].pFn = fn;
	//初始化靜態變量
	int type;
	switch (staticdata)	{
	case 4:	*(int*)subclasses[subClassIndex].pStatic = 0; break;		//int初始化爲0
	case 1:	*(char*)subclasses[subClassIndex].pStatic = 'a'; break;		//char初始化爲‘a’
	default:strcpy(subclasses[subClassIndex].pStatic, "");	break;		//string初始化爲空串
	}
	subClassIndex++;	//子類的個數增加1
}

爲了儲存子類和實例,分別又建立了兩個結構體SubClassObject,並分別開闢了兩個數組來儲存子類和實例。SubClass結構體中包含了子類的名字、子類附加變量增加字節數、子類static變量增加字節數、指向static變量的指針和一個函數指針(這裏類似C++中函數的重載)。Object結構體中儲存了類的實例,其中包含了指向類的實例的指針和一個表示子類類型的指針。

//子類
struct SubClass {
	char Name[200];	//子類名字
	int Bytes;		//子類附加變量增加字節數
	int StaticBytes;	//子類static變量增加字節數
	char* pStatic;		//子類static的指針
	int (*pFn)(int win, int msg, int param1, int param2);	//子類的方法函數
}subclasses[50];
int subClassIndex = 0;

//獲取當前創建的子類總數
int getSubClassNum() { return subClassIndex; }

//所有類的實例
struct Object {
	int object;	//類的實例
	int index;	//若爲基類的實例則是-1,若爲子類的實例則爲其在subclasses裏面對應子類的下標
}objects[100];
int objectIndex = 0;	//實例的個數

//獲取當前創建的實例總數
int getObjNum() { return objectIndex; }

關鍵細節

  1. void* p = malloc(sizeof(window) + subclasses[objects[i].index].Bytes); 開闢子類實例的內存空間。子類實例不僅要開闢基類變量所包含的內存空間(實現繼承),還要有自己的內存空間。【**注意:**子類的實例不包含子類變量的static靜態變量的內存空間。因爲靜態變量是屬於子類的,在定義子類的時候已經開闢,不屬於子類的實例。】
  2. window* p = (window*)win; 因爲在項目中所有的參數傳遞都是用指針以int類型進行傳遞,這個語句可以將int(實際上是指針)轉換爲window類型。其他類型的轉換同理。
  3. char* p = (char*)win + sizeof(window); 這一步操作本質上只是一個指針的跨越,但是它實現了對子類附加變量的指針定位。

不足之處

代碼中有一個暫未解決的bug,本來說是想實現構造函數和析構函數,但在 delete 清除實例內存的時候出現了一點問題,總是報內存泄漏的錯誤,希望路過的大佬可以幫忙完善一下,不盡感激。

//刪除窗口(暫未通過調試)
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"

//位置結構體,包含(x,y)
typedef struct Pos {	
	int x, y;
};

//窗口大小結構體,包含寬、高
typedef struct WinSize {	
	int width, height;
};

//基類
struct window {
	Pos pos;
	WinSize size;
	char title[200];
};

//子類
struct SubClass {
	char Name[200];	//子類名字
	int Bytes;		//子類附加變量增加字節數
	int StaticBytes;	//子類static變量增加字節數
	char* pStatic;		//子類static的指針
	int (*pFn)(int win, int msg, int param1, int param2);	//子類的方法函數
}subclasses[50];
int subClassIndex = 0;

//獲取當前創建的子類總數
int getSubClassNum() { return subClassIndex; }

//所有類的實例
struct Object {
	int object;	//類的實例
	int index;	//若爲基類的實例則是-1,若爲子類的實例則爲其在subclasses裏面對應子類的下標
}objects[100];
int objectIndex = 0;	//實例的個數

//獲取當前創建的實例總數
int getObjNum() { return objectIndex; }

//創建一個新的子類
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內存空間
	subclasses[subClassIndex].pFn = fn;
	//初始化靜態變量
	int type;
	switch (staticdata)	{
	case 4:	*(int*)subclasses[subClassIndex].pStatic = 0; break;		//int初始化爲0
	case 1:	*(char*)subclasses[subClassIndex].pStatic = 'a'; break;		//char初始化爲‘a’
	default:strcpy(subclasses[subClassIndex].pStatic, "");	break;		//string初始化爲空串
	}
	subClassIndex++;	//子類的個數增加1
}

//移動窗口
void move(int win, int deltaX, int deltaY) {
	window* p = (window*)win;	//將任意封裝類型強制轉化爲所需要的內容
	p->pos.x += deltaX;
	p->pos.y += deltaY;
}

//設置窗口位置
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;
}

//設置窗口寬和高
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;
}

//設置窗口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;
}

//創建Window,參數是子類名字,創建基類則傳入0
int CreateWindow(char* name) {
	int new_win = 0;
	if (!name) {	//創建基類實例
		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;	//基類的下標設置爲-1
		objectIndex++;	//實例數+1
	}
	else {	//創建子類實例
		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;	//下標設置爲在subclasses裏面相同子類的下標
				objectIndex++;	//實例數+1
				break;
			}
		}
	}	
	return new_win;
}

//基類的構造函數,初始化基類變量
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;
}

//拷貝並創建實例
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);
				//確定子類附加變量的參數類型
				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;
				//複製子類附加變量
				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;	//下標設置爲在subclasses裏面相同子類的下標
				objectIndex++;	//實例數+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;	//基類的下標設置爲-1
				objectIndex++;	//實例數+1
			}
			//複製基類變量
			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);	//獲取被複制實例的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);	//獲取被複制實例的size
			WinProc(new_win, SET_SIZE, w_size.width, w_size.height);	//賦值新實例的size

			return new_win;
		}
	}
}

//刪除窗口(暫未通過調試)
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跨越基類內存,指向子類附加內存
	if (sub_type == SUB_INT)			//子類附加的數據是int
		return *(int*)p;
	else if (sub_type == SUB_CHAR)	//子類附加的數據是char
		return *p;
	else if (sub_type == SUB_STRING)	//子類附加的數據是字符串
		return (int)p;
}

//設置子類中的變量
void setMem(int win, int  sub_type, int param2) {
	char* p = (char*)win + sizeof(window);	//指針p跨越基類內存,指向子類附加內存
	if (sub_type == SUB_INT)	//子類附加的數據是int
		*(int*)p = param2;
	else if (sub_type == SUB_CHAR)	//子類附加的數據是char
		*p = param2;
	else if (sub_type == SUB_STRING)	//子類附加的數據是字符串
		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;
}

//設置子類的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) {		//找到這個實例對應的子類
			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;
			}
		}
	}

}

//封裝的窗口操作函數
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;
	}
}

//分配基類和子類操作函數的調用接口
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)		//如果是基類,則返回基類對應的操作函數
				return WinProc(win, msg, param1, param2);
			return subclasses[objects[i].index].pFn(win, msg, param1, param2);	//如果是子類,則返回子類對應的操作函數
		}
	}
	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		//暫未通過調試

#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();	//獲取當前創建的子類總數
int getObjNum();		//獲取當前創建的實例總數
int CreateWindow(char* name);	//創建實例,參數是子類名字,基類則傳入0
int WinProc(int win, int msg, int param1, int param2);		//SDK整體封裝
int CallProc(int win, int msg, int param1, int param2);		//多態
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(主函數)如下:
//Author:SongXingJian
#include "window.h"
#include "stdio.h"

//win_num子類的函數
int sub_window_num(int win, int msg, int param1, int param2) {
	switch (msg){
		//子類構造函數,創建一個子類
	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;
		//設置子類實例附加變量
	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;
		//設置子類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子類的函數
int sub_window_c(int win, int msg, int param1, int param2) {
	switch (msg) {
		//子類構造函數,創建一個子類
	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;
		//設置子類實例附加變量
	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;
		//設置子類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";
	
	/****************** 創建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);	// 構造函數,可以創建實例,並初始化title、基類變量和實例附加變量 
	CallProc(sub_w, MEM_SET, SUB_INT, 5);		//設置實例的子類附加變量
	CallProc(sub_w, MEM_GET, SUB_INT, 0);
	CallProc(sub_w, STATIC_SET, SUB_INT, 3);	//設置實例所屬子類static變量
	CallProc(sub_w, STATIC_GET, SUB_INT, 0);
	CallProc(sub_w, PRINTWINDOW, 0, 0);			//打印窗口屬性
	//複製這個實例
	int sub_w_copy = CallProc(sub_w, COPY, 0, 0);
	CallProc(sub_w_copy, PRINTWINDOW, 0, 0);	//打印窗口屬性
	//驗證子類static變量的性質
	printf("\n\n****** 驗證子類static變量的性質 ******\n");
	CallProc(sub_w_copy, STATIC_SET, SUB_INT, 100);	//通過複製的實例修改靜態變量
	CallProc(sub_w, STATIC_GET, SUB_INT, 0);		//通過另一個實例調用
	printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());


	/****************** 創建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);	// 構造函數,可以創建實例,並初始化title、基類變量和實例附加變量 
	CallProc(sub_w_c, MEM_SET, SUB_CHAR, (int)'B');		//設置實例的子類附加變量
	CallProc(sub_w_c, MEM_GET, SUB_CHAR, 0);
	CallProc(sub_w_c, STATIC_SET, SUB_CHAR, (int)'S');	//設置實例所屬子類static變量
	CallProc(sub_w_c, STATIC_GET, SUB_CHAR, 0);
	CallProc(sub_w_c, PRINTWINDOW, 0, 0);				//打印窗口屬性
	//複製這個實例
	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());


	/****************** 創建基類 ******************/
	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);	//設置窗口位置
	CallProc(base_w, MOVE, 2, 2);			//移動窗口
	CallProc(base_w, SET_SIZE, 5, 5);		//設置窗口大小
	CallProc(base_w, PRINTWINDOW, 0, 0);	//打印窗口屬性
	printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章