📄 cexample.c
字号:
/*************************************************************************** CExample.c A component example (c) 2000-2003 Beno顃 Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************//* This file is used for implementing a class and its possible virtual classes. What is a virtual class ? It is a class that represents a sub-component of a class, but that you cannot instanciate nor reference into a variable. For example, the property Item of the ListBox class is a virtual class that represents a ListBox item. Virtual classes are just used as datatypes by the interpreter. But the object used behind is the real object coming from the real non-virtual class. For example, the Item property of the ListBox class stores the index of the item you want to deal with in the ListBox object, and returns this ListBox object. The ListBox object becomes then a virtual class object that you cannot store in a variable. As you must use the virtual class object immediately, by calling a method or a property on it, the stored index will be used immediately too. This mechanism has been designed so that the user manipulates temporary objects, without being compelled to create them. It is SO faster ! Note that the name of a virtual class must begin with a dot. For example, the name of the virtual class used by the Item property is ".ListBoxItem". You can declare several classes in the same file, but you should generally avoid that. It is clearer this way.*/#define __CEXAMPLE_C/* You can put there the system includes you need */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>/* You must include main.h, to get a reference to the Gambas interface through the GB structure.*/#include "main.h"/* Then you include the header of the class */#include "CExample.h"/* If your class raise events, you must declare them with the DECLARE_EVENT macro. */#ifndef THIS_IS_JUST_AN_EXAMPLEDECLARE_EVENT(FirstEvent);DECLARE_EVENT(SecondEvent);#endif/* Then we implement the method and the properties of the class. First, we will begin with an example of each.*//* To implement a method, you must write a function whose code is enclosed between the two macros: BEGIN_METHOD and END_METHOD. The BEGIN_METHOD macro takes TWO arguments: the function name, and a list of arguments separated by semicolons. The method arguments are NOT separated by commas, because they are in reality fields of a structure passed to the function. If your method takes no argument, you must use BEGIN_METHOD_VOID instead of BEGIN_METHOD. The BEGIN_METHOD_VOID function takes only one argument, the name of the function. The include gambas.h contains definitions for the argument types: - GB_BOOLEAN for a boolean argument. - GB_INTEGER for an integer argument. - GB_FLOAT for a double argument. - GB_STRING for a string argument. - GB_DATE for a date argument. - GB_VARIANT for a variant argument. - GB_OBJECT for a object reference. You MUST use these datatypes ! To get the parameters, you have two macros : ARG() and VARG(). The ARG() macro returns the address of the parameter in the interpreter stack, and is used with functions like GB.ToZeroString(), or GB.Store() functions. The VARG() macro returns the value of the parameter.*/#ifndef THIS_IS_JUST_AN_EXAMPLEBEGIN_METHOD ( TheFunctionName , GB_INTEGER anInteger; GB_STRING aString; GB_VARIANT aVariant; GB_BOOLEAN aBoolean; ) /* To get the value of a parameter, you must use the VARG macro. */ printf("anInteger = %d\n", VARG(anInteger)); /* To get a string parameter, you must use the special macros STRING and LENGTH to get the address of the string and its length. */ printf("aString = %*.s\n", LENGTH(aString), STRING(aString)); /* You can also transform the Gambas string into a C zero-terminated string with the GB.ToZeroString function. You must use the ARG macro to get the parameter address, and not the VARG macro that returns its value. */ printf("aString = %.s\n", GB.ToZeroString(ARG(aString))); /* GB_VARIANT is a union of different datatypes. The type field of this union is one of the GB_T_* constants. */ if (VARG(aVariant).type == GB_T_STRING) printf("I got the following string: %s\n", VARG(aVariant)._string.value); /* GB_BOOLEAN is stored as an integer, which is zero when FALSE, and different from zero when TRUE. */ printf("aBoolean = %s\n", VARG(aBoolean) ? "TRUE" : "FALSE"); /* If you want to raise an error into your method, you must use the GB.Error() function to register the error, and returns immediately after. */ if (VARG(aBoolean)) { GB.Error("There was an error !"); return; } /* To return a value from the method, you can use the GB.Return<Type>() interface functions : GB.ReturnInteger() to return a integer, GB.ReturnBoolean() to return a boolean, etc. */ GB.ReturnInteger(VARG(anInteger) * 2);END_METHOD#endif/* To implement a property, you must write a function whose code is enclosed between the two macros : BEGIN_PROPERTY and END_PROPERTY. The BEGIN_PROPERTY macro takes one argument : the property name. The function is called both for reading and writing the property. To distinguish between the two cases, you must use the READ_PROPERTY macro. Of course, if your property is read-only, this is not necessary. When reading the property, you must return the property value with one of the GB.Return<Type> functions. When writing the property, you get the value to write with the VPROP macro. This macro takes one argument : the datatype of the property, which must be one of the datatype macro defined in gambas.h : - GB_BOOLEAN for a boolean property. - GB_INTEGER for an integer property. - GB_FLOAT for a double property. - GB_STRING for a string property. - GB_DATE for a date property. - GB_VARIANT for a variant property. - GB_OBJECT for a object reference property. Use the PROP macro to get the address of the value, if you want to use functions like GB.ToZeroString() or GB.Store() for example.*/#ifndef THIS_IS_JUST_AN_EXAMPLEBEGIN_PROPERTY ( ThePropertyName ) /* First, you must check if we want to read or to write the property. */ if (READ_PROPERTY) { /* Here we are reading the property */ printf("Returns the property value\n"); /* The THIS macro is defined in the class header file. It returns a pointer to the data of the object structure. We suppose here that there is a char *AStringProperty defined in the object structure, and that char * points to a Gambas string. */ GB.ReturnString(THIS->AStringProperty); } else { /* Here we are writing the property */ /* To store a complex Gambas datatype like String or Object, you must use GB.StoreString() or GB.StoreObject(). These functions deals with reference counting. */ printf("I'm going to write the value: %s\n", GB.ToZeroString(PROP(GB_STRING))); GB.StoreString(PROP(GB_STRING), &THIS->AStringProperty); /* Generally, a modified property implies some other actions */ printf("Property has been modified. The new value is %s\n", THIS->AStringProperty); }END_PROPERTY#endif/* Here are the real implementations of the CExample class methods and properties...*/BEGIN_METHOD(CEXAMPLE_new, GB_INTEGER width; GB_INTEGER height; GB_INTEGER data) THIS->data = (unsigned long *)VARG(data); THIS->width = VARG(width); THIS->height = VARG(height);END_METHODBEGIN_METHOD_VOID(CEXAMPLE_free) /* Nothing to do */END_METHODBEGIN_PROPERTY(CEXAMPLE_width) GB.ReturnInteger(THIS->width);END_PROPERTYBEGIN_PROPERTY(CEXAMPLE_height) GB.ReturnInteger(THIS->height);END_PROPERTYBEGIN_METHOD_VOID(CEXAMPLE_hflip) int i, i2, j, w, h; unsigned long *d; unsigned long c; w = THIS->width; h = THIS->height; d = THIS->data; for (j = 0; j < h; j++) { for (i = 0, i2 = (w - 1); i < (w / 2); i++, i2--) { c = d[i]; d[i] = d[i2]; d[i2] = c; } d += w; }END_METHODBEGIN_METHOD_VOID(CEXAMPLE_vflip) int i, j, w, h; unsigned long *d, *d2; unsigned long c; w = THIS->width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -