Copyright: (c) 1992 - 1996 Corel Corporation. All rights reserved.
Citation: (c) 1992 - 1996 Corel Corporation. All rights reserved.


Corel Click & Create Extension Development Kit


Welcome to the Corel Click & Create extension development kit!


Overview: Welcome to the Corel Click & Create extension development kit!
Welcome to the Corel Click & Create extension development kit!

The Click & Create extension development kit will enable you to create your own individualized objects for use in Click & Create. Each object can have it's own behavior and specialized conditions and actions. In order to begin creating your own extension objects, you will need:

•	Visual C++ 1.5 (for use with the 16-bit version of Click & Create)

•	Visual C++ 4.0 (for use with the 32-bit version of Click & Create)

•	A good knowledge of C programming

•	Lots of ideas!

We have created a template file to make it quick and easy for you to create your first extension object. All you need to do is fill in the spaces in the template to customize your object. This template file is designed to compile quickly on your machine.

The Click & Create extension development kit is a very powerful tool that comes with extensive documentation. We suggest that you take the time to discover the extension development kit slowly, step by step, in order to fully understand it. A good object to create for your first attempt, is a special movement object that collides with everything and generates a database of collisions. Another suggestion is an invisible object that just makes a BEEP sound or prints the word "Hello!" on the screen.

After you have mastered the techniques needed to create these simple objects, add more actions and conditions to create more complex objects. Try to add a routine that will draw the object you've created in the frames.

Corel and Europress would definitely like to see your creations, and there might be an opportunity for you to make money with new objects you've created.

Other extension kits will be released over the course of the year to work under Borland C++ and even Delphi. Please feel free to contact us to discuss any problems, questions, or suggestions that you may have regarding the development kit at:

Internet E-mail:	clickcreate@corel.ca

WWW site:	www.corel.com/click&create

You can also find more information on the following web pages:

www.corel.com

www.europress.co.UK

Thanks for your interest in Corel Click & Create!

Yours sincerely,

François Lionet

For more information see the following:

 List of files

 Files found in the "Template" folder

 Files found in the "Inc" folder

 Files found in the "Lib" folder

 Related Topics


List of files


Overview: List of files
List of files

This chapter contains the different files that you will find in the extension development kit.

The extension kit contains the following elements:

•	 Documentation

•	 Ext16.mak

•	 Ext32.mak

 Related Topics


Documentation

If you can read this file, it means that you already found it!

 Related Topics


Ext16.mak

16-bit make file, included by every extension make file. You may need to change some of the directories in this file.

 Related Topics


Ext32.mak

32-bit make file, included by every extension make file. You may need to change some of the directories in this file.

 Related Topics


Files found in the "Template" folder


Overview: Files found in the "Template" folder
Files found in the "Template" folder

The Template folder contains the following files:

•	 Ext.c

•	 Ext.h

•	 ExtObj.rc

•	 Extrc.h

•	 ExtObj.def

•	 ExtObj32.def

•	 ExtObj.mak

•	 ExtObj32.mak

•	 Extcur.cur

•	 Exticon.bmp

•	 Extimg.bmp

•	 Exttool.bmp

•	 Proj32

•	 Winrel

 Related Topics


Ext.c

The Ext.c folder contains the extension source code, written in C.

 Related Topics


Ext.h

The Ext.h folder contains a header file that identifies controls for the extenison object.

 Related Topics


ExtObj.rc

The ExtObj.rc folder contains the extension resources.

 Related Topics


Extrc.h

The Extrc.h folder contains a header file that identifies controls for the extension object.

 Related Topics


ExtObj.def

The ExtObj.def folder contains the 16-bit definition file.

 Related Topics


ExtObj32.def

The ExtObj32.def folder contains the 32-bit definition file.

 Related Topics


ExtObj.mak

The ExtObj.mak folder contains the 16-bit make file, for Visual C++ V1.5

 Related Topics


ExtObj32.mak

The ExtObj32.mak folder contains the 32-bit make file, for Visual C++ V4.0

 Related Topics


Extcur.cur

The Extcur.cur folder contains the definition of the cursor when you drop the extension object on a frame.

 Related Topics


Exticon.bmp

The Exticon.bmp folder contains the icon of the object in the "Frame object" window in the Frame editor.

 Related Topics


Extimg.bmp

The Extimg.bmp folder contains the image of the object displayed in the frame in the Frame editor.

 Related Topics


Exttool.bmp

The Exttool.bmp folder contains the icon of the object in the "Create new object" dialog box.

 Related Topics


Proj32.*

Proj32 folder contains Visual C++ 4.0 project files. The real project is called Proj32, and uses an external make file. You could also compile the extension from a DOS session by launching nmake with extobj32.mak.Windebug

The Proj32 Folder contains two subfolders: 16- and 32-bit, for compiling under the 16- and 32-bit versions. Each of these folders also contains debugging information.

 Related Topics


Winrel

The Winrel folder contains two subfolders: 16- and 32-bit, for compiling under the 16- and 32-bit versions. These folders don't contain debugging information.

 Related Topics


Files found in the "Inc" folder


Overview: Files found in the "Inc" folder
Files found in the "Inc" folder

The Inc folder contains the following files:

•	 Ccx.h

•	 Ccxhdr.h

•	 Cnpdll.h

•	 Cnpdll.inc and Cnpdll.i32

•	 Cnpf.h

•	 Cnpf.inc and Cnpf.i32

•	 Cnpy.h

•	 Cnpy.inc and Cnpy.i32

•	 Ptype.h

•	 Ptype.inc and Ptype.i32

 Related Topics


Ccx.h

The Ccx.h folder contains important definitions to be included in an extension object.

 Related Topics


Ccxhdr.h

The Ccxhdr.h folder is included in ext.c. This file makes sure all the necessary .h files are included.

 Related Topics


Cnpdll.h

The Cnpdll.h folder contains all the definitions and functions of CNCS.DLL

 Related Topics


Cnpdll.inc and Cnpdll.i32

The Cnpdll.inc and Cnpdll.i32 folders contain all the definitions and functions of CNCS.DLL if you want to program in machine language, in 16- or 32-bit.

 Related Topics


Cnpf.h

Cnpf.h is part of the main Corel Click & Create definitions. This file contains the majority of the information on events, actions, conditions, editors, and run-time object structures.

 Related Topics


Cnpf.inc and Cnpf.i32

Cnpf.inc and Cnpf.i32 are the Cnpf.h file converted from machine language in 16- and 32-bits.

 Related Topics


Cnpy.h

Cnpy.h is part of the main Corel Click & Create definitions. This file includes the application structures and data storage definitions.

 Related Topics


Cnpy.inc and Cnpy.i32

Cnpy.inc and Cnpy.132 are the Cnpy.h file converted from machine language in 16- and 32-bits.

 Related Topics


Ptype.h

The Ptype.h folder contains the 16 / 32 compatibility library. The compatibility library contains useful macros that enable you to program in both 16- and 32-bit using one source code.

 Related Topics


Ptype.inc and Ptype.i32

Ptype.inc and Ptype.i32 are the Ptype.h file converted from machine language in 16- and 32-bits.

 Related Topics


Files found in the "Lib" folder


Overview: Files found in the "Lib" folder
Files found in the "Lib" folder

The Lib folder contains the following files:

•	 Cncs.lib

•	 Cncs32.lib

 Related Topics


Cncs.lib

The Cncs.lib folder contains the CNCS.DLL system library include in 16-bits.

 Related Topics


Cncs32.lib

The Cncs32.lib folder contains the CNCS32.DLL system library include in 32-bits.

 Related Topics


Example objects


Overview: Example objects
Example objects

The Example objects folder contains four sub-folders:

•	Clock

•	INI

•	Edit

•	RTF

Each of these folders contain the source code for the Clock, INI, Edit, and RTF objects as they appear in the first version of Click & Create. Use these files as examples of fully-completed and working Click & Create extension objects.

The RTF folder contains one part of the RTF object that interfaces between the RTF engine and Click & Create. This file cannot be compiled.

The source codes are given "as they are" and we have made no special effort to add comments to the code (sorry!). Some of the comments are still in French (pardon!). You should be able to open the project under VC++1.5 or VC++4.0 and compile immediately.

Why we chose these objects?

We chose to include the source code for the INI, Clock, Edit, and RTF objects because:

•	The INI object is a good example of an object with no output in the application frame.

•	The Clock object is a good example of an object that draws itself in the frame.

•	The Edit object is a good example of an object that opens a control over the application frame, and intercepts the main window messages.

•	The RTF object is a complex object that at the same time, draws on the screen and controls two scroll bars. This object contains a great deal of useful information.

 Related Topics


Create your extension, step by step


Overview: Create your extension, step by step
Create your extension, step by step

The Click & Create extension development kit contains a template that you can use to help you create your own extension objects in minutes. This chapter will take you through the following steps in the development process:

•	 Compile in 5 minutes

•	 Change the name and the icons

•	 Choose the properties

•	 Create the setup dialog

•	 Create the run-time routines

•	 Define conditions, actions, or expressions

•	 Debugging your extension object

 Related Topics


Compile in 5 minutes

The Corel Click & Create extension kit comes with a ready-to-assemble extension template. This template generates an empty extension with one action, one condition, and one expression that does —basically nothing. You will have to fill in the gaps in this template to define your own routines in the source code.

The first task is for you to compile this template properly.

1.	Unzip or copy the content of the CCX_KIT folder into another directory

2.	Rename the "Template" directory to the name of your extension object

If you have both Visual C++ 1.5 and 4.0, we suggest that you use 4.0 to start.

 Related Topics


Visual C++ 1.5 (16-bit version)

1.	Edit EXTOBJ.MAK in an ASCII editor and insert the name of your extension object at the beginning of the file. No extension is necessary!

2.	In the next line, insert the name of any additional libraries that will eventually be added.

3.	Edit EXTOBJ.DEF in an ASCII editor and insert the name of your extension object in the first line. Replace the description on the top line with your own description.

Warning: The name used for the extension object, must be the same as the name used in the .MAK file.

4.	Boot Visual C++ 1.5, choose option PROJECT / OPEN, select the file EXTOBJ.MAK from your extension directory. Enable the "Use as an external makefile" checkbox.

5.	Choose the menu OPTIONS / PROJECT and make sure that the settings are correct:

6.	Project type: Dynamic Linked Library, Build mode: Debug (at first!)

7.	Debug Build: NMAKE /f EXTOBJ.MAK "DEBUG=2" extobj.exe

8.	Release build: NMAKE /f EXTOBJ.MAK "DEBUG=0" extobj.exe

9.	Enter the pathname to your CNC.EXE file in the Debug Target Name field.

10.	You should now be able to compile the project using the PROJECT / REBUILD ALL option.

11.	You will find the compiled object in its own directory, it must be copied into your CNC.EXE directory so that it appears in the Create new object dialog box.

12.	You can, if you want, compile directly into the CNC.EXE directory. Simply enter the destination directory in the DESTDIR entry of EXT.MAK

 Related Topics


Visual C++ 4.0 (32-bit version)

1.	Edit EXTOBJ32.MAK in an ASCII editor and insert the name of your extension object at the beginning of the file. No extension is necessary!

2.	In the next line, insert the name of any additional libraries that will eventually be added.

3.	Edit EXTOBJ32.DEF in an ASCII editor and insert the name of your extension object in the first line. Replace the description on the top line with your own description.

Warning: The name used for the extension object, must be the same as the name used in the .MAK file.

4.	Boot Visual C++ 4.0, choose FILE / OPEN WORKSPACE, and choose the file PROJ32 in your extension directory.

5.	Choose the option BUILD / SETTINGS, highlight the DEBUG version, and make sure that the Build command line option reads: NMAKE /nologo /f EXTOBJ32.MAK "DEBUG=2" XXXXX.cox where XXXXX is the name of your extension object.

6.	Highlight the RELEASE version, and make sure that the Build command line option reads: NMAKE /nologo /f EXTOBJ32.MAK "DEBUG=0" XXXXX.cox where XXXXX is the name of your extension object.

7.	You should now be able to compile the project using the BUILD / REBUILD ALL option.

8.	You will find the compiled object in its own directory, it must be copied into your CNC32.EXE directory so that it appears in the Create new object dialog box.

9.	You can, if you want, compile directly into the CNC32.EXE directory. Simply enter the destination directory in the DESTDIR entry of EXT32.MAK

 Related Topics


Change the name and the icons

When creating an extension object, the first thing you'll want to do is to define your own icons. These icons are defined as external BMP files.

About the resource editor

The Visual C++ resource editor, AppStudio is a great program, but sometimes problems occur with the resource file. This can be a problem for extension objects, as some strings and pop-up menu identifiers are obtained by adding two identifiers, and Visual C++ does not like this.

If you own Borland C++, we highly suggest you use WorkShop to edit the resource. If you don't, you should edit the resource file directly in ASCII (this method is a lot faster).

To define the Setup dialog box, we suggest that you use AppStudio or another resource file, and then cut and paste the dialog definition in your object resource file.

To edit the bitmaps, use any paint package, for example Corel PhotoPaint.

Change the bitmaps

•	Exticon.bmp: Icon of the object in the "Frame object" window in the Frame editor. Corel Click & Create defines black as the transparent color therefore, you should use a dark blue instead of black.

•	Extimg.bmp: Image of the object displayed in the playfield in the Frame editor. You should make this icon look 3 dimensional so that it can be easily identified on the playfield.

•	Exttool.bm:p Icon of the object in the "Create new object" dialog box. This icon is automatically centered in the button and you don't need to worry about drawing the button itself. The background color should be light-gray, because Corel Click & Create remaps this color to the user-selected color, if the user has changed their desktop settings.

•	Extcur.cur This cursor is used when you drop the object on the playfield. Usually we just paste the shape of extimg.bmp in it.

Change the strings

In Extobj.rc: you will find different strings describing the object.

KPX_NAME: the name of the object, displayed when the mouse moves over the object.

KPX_CREATETITLE: the hint you get in the Create new object dialog box.

M_DESC: this string is displayed in the information bar in the bottom of the screen when the mouse moves over the object. "%s" is replaced by the name of the object (defined in KPX_NAME).

VERSIONINFO FIELDS: insert your name and copyright information here.

 Related Topics


Choose the properties

When defining an extension object, it's important to decide if your object should move, be animated, open a window over the frame, open a control, or simply be invisible. All these decisions have made at this time.

Once you have decided on the properties of your object, read the chapter "Defining the object properties" and enter the good OEFLAGS and OEPREFS in the .H file.

 Related Topics


Create the setup dialog

What information does your object need? Does it need a pathname, numbers, flags etc. All this information has to be stored in the EDITDATA structure. First, have a look at the "Important structures" chapter and then define your EDITDATA structure.

I suggest that you to define several free fields just in case you need future extensions for your structure. This will allow you to add data to the object without the need of a new version and a conversion routine.

If you decide to store a pathname in the EDITDATA structure, then use the _MAX_PATH variable as maximum length of the pathname fields. You also have to implement the UpdateFileNames routine so that the pathnames are relocated when the application is moved.

Once your EDITDATA structure is created, you can start your setup dialog box. This dialog should be called by two routines: CreateObject and SelectPopup. Have a look at the examples (EDIT, INI, EDIT) objects dialog box.

 Related Topics


Create the run-time routines

If you have compiled the template, changed the name and icons, chosen the properties and created the setup dialog, you are now ready to drop your object in the frame, and call the setup dialog box. The next step is to make it live in run-time.

Two routines are absolutely crucial to the development of an extension object:

•	CreateRunObject

•	DestroyRunObject

The CreateRunObject routine is called when the object is created, and the RUNDATA structure is initialized from the information found in the EDITDATA structure. Usually the RUNDATA structure reflects the EDITDATA structure, and has more fields to handle run-time data. CreateRunObject is the only link between EDITDATA and RUNDATA, and therefore you should copy all the necessary information there. DestroyRunObject is called when the object is destroyed. This routine should free any memory that is allocated, windows that are opened, or resources that are loaded during the life of the object.

Another routine of importance is HandleRunObject. This routine is called at every loop of the application. Please, make this routine as fast as possible: a slow routine will slow down the entire application. For example, the search object only look for 100 lines of text at each loop. If the HandleRunObject routine is fast, the user will still be able to have animations running while the object is looking for the requested text.

If your object is invisible, go to the "Define conditions, actions, or expressions" chapter. If not, you will need to fill the DisplayRunObject routine with your code. Remember two things:

•	DisplayRunObject is the only place where you can write on the screen, so that the background saving and restore process works.

•	You must not use GetDC to get a device context in the frame window. Use the CNCS.DLL primitives instead. Read the CNCS graphics section for more information.

 Related Topics


Define conditions, actions, or expressions

Conditions, actions, and expressions are essential parts of your extension object. The following example will explain how to create a new condition. Use the same technique to create actions and expressions for your object.

1.	Think about your condition! Find a good name for both the pop-up menu and the display in the Event Editor. Does it need parameters, which one etc? Here, we are going to make a condition that will ask for a numeric parameter.

2.	Define the code for the condition in the EXT.H file and locate the CND_LAST value. Replace the name with the codename of your condition, for example CND_MINE, and define CND_LAST to be your last condition plus 1 (CND_LAST should always be the last one defined, plus one).

3.	Edit the file EXTOBJ.RC using an ASCII editor. Define a new option in the MN_CONDITIONS menu with an entry for your new condition, such as "This condition of mine". Make sure that the identifier of the menu option is: (ID_MENUCONDITIONS+CND_MINE)

4.	In the EXTOBJ.RC file, locate the stringtable just after the condition pop-up menu (You should still be editing this file in the ASCII editor). Enter a new string to be used to display your condition. For example "11%s: what a nice condition s%". Make sure that the identifier of this string is (M_DISPCONDITIONS+CND_MINE) Please refer to the chapter about condition/action display strings.

5.	Load EXT.C and locate the conditionsInfos array. Enter a new line of definitions at the exact position as defined by CND_MINE (so that Corel Click & Create can refer to this line using conditionInfos[CND_MINE]), and enter for example: {CND_MINE, EVFLAGS_ALWAYS, PARAM_EXPRESSION,0,0,0}. Please refer to the eventInfos structure for more information.

6.	In EXT.C define a new routine to handle your new condition. For example, short WINAPI DLLExport ConditionOfMine(LPRDATA rdPtr, long param1, long param2). Please refer to List of run-time routines for more information on this routine.

7.	Now locate the ConditionJumps array, and at the exact position as defined by the code CND_MINE, insert the name of your new routine. In this example, the name is "ConditionOfMine".

 Related Topics


Debugging your extension object

Debugging the code for your extension object is a very important step in the development process. You will certainly need to step through the code in order to solve any problems and fix any bugs. The following sections contains procedures to follow to access the source code of your extension under a debugger. There are two different procedures:

•	 Debugging in Visual C++ 1.5

•	 Debugging in Visual C++ 4.0

 Related Topics


Debugging in Visual C++ 1.5

If you are using Visual C++ 1.5 to debug the code for your extension object, you'll have to use Codeview. Codeview is very buggy when it comes to debugging external DLLs but once you get used to it, you will be able to work with it and complete the task successfully.

1.	Compile your extension with debug information! Seems trivial, but I remember spending one hour fighting with Codeview and then realized it was my fault that it wasn't working!

2.	Launch CNC.EXE under Codeview using the following command line: /L\path_to_my_extension\my_ext.ccx \path_to_my_cnc\CNC.EXE

3.	Select the FILE / OPEN MODULE menu option, you should find you extension sourcecode there.

4.	Open your source code and set a breakpoint in it. CodeView should accept this breakpoint.

5.	Run CNC and when Codeview hits the breakpoint, it will allow you to step through your extension.

6.	Sometimes, Codeview breaks in the extension, but does not display the source code. In this case, you should exit Codeview and restart it with another, completely different application, exit again, reboot the machine, and then debug your extension. Codeview should now properly display the source code.

 Related Topics


Debugging in Visual C++ 4.0

1.	Under Visual C++ 4.0, choose the BUILD/SET DEFAULT CONFIGURATION option, and set it to Debug.

2.	Choose the BUILD/SETTINGS option, in the dialog box, highlight only the Debug project, then click the Debug tab. Make sure that General is selected in the category combo box.

3.	Enter the pathname to your copy of CNC32.exe in the field Executable for debug session.

4.	Enter the directory of your CNC32 in the Working directory field.

5.	Select the Additional DLLS in the Category combo box.

6.	Enter the path to your object.COX (it must be copied in your CNC32.EXE directory!) in the Modules/Local Names list.

You should now be able to set a breakpoint directly in your extension source code (F9) and step-through it.

 Related Topics


Defining the object properties


Overview: Defining the object properties
Defining the object properties

Before jumping straight into coding, you should take some time to decide what properties your object should have. For example, should it move, use an animation like an active object, should it be used in its own window, etc. You must tell Corel Click & Create about all of the properties for your object.

In the GetRunObjectInfos routine, the extension must fill two flag-fields:

•	infoPtr->editFlags=OEFLAGS;

•	infoPtr->editPrefs=OEPREFS;

The first flag field contains the current flags for the object (the object is going to be created using these flags when you drop it onto the playfield). These flags can be changed later using the extension setup.

The second field contains the edition flags and allows certain properties to be edited as the extension prefers.

OEFLAGS and OEPREFS are defined at the end of EXT.H file.

For more information see the following:

 OEFLAGS

 OEPREFS

 Examples of objects and flags

 Related Topics


OEFLAGS


Overview: OEFLAGS
OEFLAGS

OEFLAGS are very important in your extension object. Click & Create uses these flags to determine whether the object is to be treated as a sprite, backdrop, or quick backdrop object. These flags also determine whether or not the movement properties have to be appended, etc.

Main properties of OEFLAGS

The main properties of OEFLAGS are:

•	 Movements

•	 Animations

•	 Values

 Related Topics


OEFLAG_MOVEMENTS

The OEFLAG_MOVEMENTS flag appends a movement property to the object. If you use this flag you must include the rCom and rMov structures in the run-data structure of the object.

 Related Topics


OEFLAG_ANIMATIONS

The OEFLAG_ANIMATIONS flag appends a sprite-based animation property to the object. If you use this flag you must include the rCom and rAni structures in the run-data structure of the object.

If an object has both the OEFLAG_ANIMATIONS and OEFLAG_SPRITE flags, the display will be automatically be done by Click & Create. Therefore, you do no need to define any drawing routine in your extension.

 Related Topics


OEFLAG_VALUES

The OEFLAG_VALUES flag appends a value property to the object which contains 3 alterable values (A, B, and C) and a string. If you use this flag you must include the rVal structures in the run-data structure of the object.

 Related Topics


Display properties


Overview: Display properties
Display properties

The main display properties of OEFLAGS are:

•	 Background

•	 Sprites

•	 Backsave

•	 Internal Backsave

•	 Quickdisplay

We will also look at the case that there is No OEFLAG_SPRITE or OEFLAG_BACKGROUND.

 Related Topics


OEFLAG_BACKGROUND

OEFLAG_BACKGROUND tells Click & Create to display this object in the middle of the background objects.

Note: This flag should be used with caution. Use this flag only for objects that are not updated very often and that don't move. Whenever the object changes, the entire screen is redrawn. The Picture object is an example of an object that uses the OEFLAG_BACKGROUND routine. There is NO background saving for this object, because the complete screen is re-generated from scratch each time this object has to be redrawn. This flag should not be used with OEFLAG_SPRITES and OEFLAG_QUICKDISPLAY, etc.

 Related Topics


OEFLAG_SPRITES

OEFLAG_SPRITES tells Click & Create to handle this extension object as a sprite.

If the OEFLAG_ANIMATIONS flag is also set, Click & Create will use a true sprite to display the object and you don't need to write a line of code. Only OEFLAG_BACKSAVE will have an effect.

 Related Topics


OEFLAG_BACKSAVE

Click & Create will save the background of the object if the flag is set, and will not save the background if the flag is not set. The zone saved is computed from the coordinates of the object and the hoImgXHot, hoImgYHot, hoImgWidth, hoImgHeight fields returned by the HandleRunObject routine.

 Related Topics


OEFLAG_INTERNALBACKSAVE

If the OEFLAG_INTERNALBACKSAVE flag is set and the OEFLAG_BACKSAVE flag is also set, Click & Create will call the extension background saving routines (which MUST be defined!). SaveBackground must save the background into a buffer and RestoreBackground must restore the saved buffer at the same coordinates. KillBackground must erase the buffer from memory.

The extension object can use the fields :

•	HGLOBAL	hoHgBack

•	ulong	hoAdBack

•	RECT	hoRectSave

from the headerObject structure.

 Related Topics


OEFLAG_QUICKDISPLAY

Displaying an object as a true sprite can slow down your application a great deal. If your object is slow to display (for example, you have created a large text object using many Windows text functions) each time another sprite is displayed in front of the object, the object must be erased and redrawn. This will cause your application to run very slowly.

To prevent your object from being redrawn every time, use the QUICKDISPLAY flag. This flag can only be used in conjunction with the OEFLAG_SPRITE flag. Such a sprite is removed from the main sprite list, but drawn just on the top of the backdrop. When a sprite comes in front, it is not redrawn. Therefore, you can have a big text displayed under moving sprites at full speed.

QUICKDISPLAY objects can or cannot save the background depending on the OEFLAG_BACKSAVE and OEFLAG_INTERNALBACKSAVE flags. One thing these flags don't do properly is handle the background saving when they cross each-other. Some parts of the second object can or cannot be saved as part of the background saved area, and vice versa. The conclusion is not to put quickbackground objects on top of each other.

 Related Topics


No OEFLAG_SPRITE or OEFLAG_BACKGROUND

If you don't use either the OEFLAG_SPRITE or the OEFLAG_BACKGROUND flag, you cannot directly access the Click & Create bitmap. This does not mean that you cannot display anything, your DisplayRunObject routine can be used to open, move, or resize a window on the top of the Click & Create screen.

We actually use this technique for the AVI, QuickTime, Button, List, Edit, and Combo objects.

 Related Topics


Other properties of OEFLAGS


Overview: Other properties of OEFLAGS
Other properties of OEFLAGS

Other properties of OEFLAGS include:

•	 OEFLAG_DISPLAYINFRONT

•	 OEFLAG_WINDOWPROC

•	 OEFLAG_TABSTOP

•	 OEFLAG_SCROLLINGINDEPENDANT

•	 OEFLAG_NEVERKILL

•	 OEFLAG_RUNBEFOREFADEIN

•	 OEFLAG_MANUALSLEEP

 Related Topics


OEFLAG_DISPLAYINFRONT

If you set the OEFLAG_DISPLAYINFRONT flag, the object will be displayed in front of all the other objects in the editor. You should use this flag when your object is displayed as a window so that the editor reflects the display that you get within the application.

 Related Topics


OEFLAG_WINDOWPROC

If your object needs to handle Click & Create window messages, you have to set the OEFLAG_WINDOWPROC flag. Click & Create will call a "WindowProc" routine in the extension object.

See: How to control a window from an extension.

 Related Topics


OEFLAG_TABSTOP

Controls, such as the Edit object or the List object, need to be activated using the TAB key. Use the OEFLAG_TABSTOP flag if you want your object to intercept tabulation commands.

Please look at the source code for the Edit object for a running example of tab.

 Related Topics


OEFLAG_SCROLLINGINDEPENDANT

If the OEFLAG_SCROLLINGINDEPENDANT flag is set, the object will not follow the playfield when it scrolls. Therefore, the object will remain static on the display, like a Score or Lives object.

 Related Topics


OEFLAG_NEVERKILL

Set the OEFLAG_NEVERKILL flag to prevent an object from being destroyed if it goes to far outside the edges of the playfield.

 Related Topics


OEFLAG_RUNBEFOREFADEIN

Use the OEFLAG_RUNBEFOREFADEIN flag with caution. This flag should not be set unless the extension object is a true sprite. (OEFLAG_SPRITES+OEFLAG_ANIMATIONS).

 Related Topics


OEFLAG_MANUALSLEEP

Usually, an object is deactivated if it's too far from the display window — it still exists, but it is removed from the display window. The decision of whether or not to deactivate this object is usually done by Click & Create. If the object is not controlled by a player, and is not part of a collision detection, then it can be deactivated. If not, then it will stay alive even if it's far from the display area.

OEFLAG_MANUALSLEEP changes this process to manual mode. In this case the flag OEFLAG_NEVERSLEEP is used as a trigger and if set the flag is set, the object will never be deactivated.

 Related Topics


What can you change in the setup of your object?


Overview: What can you change in the setup of your object?
What can you change in the setup of your object?

The setup dialog box for your extension object can be used to change any of the flags except:

•	OEFLAG_MOVEMENTS

•	OEFLAG_VALUES

•	OEFLAG_BACKGROUND

These three flags are set only once for each object.

If the flag OEFLAG_SPRITE can be used, then your run-time structure MUST include the rCom and rSpr sub-structures. When you remove the OEFLAG_SPRITE flag the rSpr structure will simply not be used.

 Related Topics


Overview: The structures you must use in your runHeader structure
The structures you must use in your runHeader structure

The basic RUNDATA structure contains the headerObject structure as the first element:

typedef struc tagRDATA

{

headerObject rHo;

} RUNDATA;

If the OEFLAG_MOVEMENTS, OEFLAG_ANIMATIONS or OEFLAG_SPRITES flags are set, you must add the rCom structure after the rHo structure:

typedef struc tagRDATA

{

headerObject rHo;

rCom rc;

} RUNDATA;

If the OEFLAG_MOVEMENTS flag is also set, you must add the rMvt structure immediately after the rCom structure.

typedef struc tagRDATA

{

headerObject rHo;

rCom rc;

rMvt rm;

} RUNDATA;

Here are the different cases:

OEFLAG_MOVEMENTS

headerObject	rHo;

rCom	rc;

rMvt	rm;

OEFLAG_ANIMATIONS

headerObject	rHo;

rCom	rc;

rAni	ra;

OEFLAG_SPRITE

headerObject	rHo;

rCom	rc;

rSpr	rs;

OEFLAG_VALUE

headerObject	rHo;

rVal	rv;

OEFLAG_MOVEMENTS | OEFLAG_ANIMATIONS

headerObject	rHo;

rCom	rc;

rMvt	rm;

rAni	ra;

OEFLAG_MOVEMENTS | OEFLAG_ANIMATIONS|OEFLAG_SPRITE

headerObject	rHo;

rCom	rc;

rMvt	rm;

rAni	ra;

rSpr	rs;

If the above combinations include OEFLAG_VALUE, you should put rVal as last element.

Remember:

•	rCom MUST be present if OEFLAG_MOVEMENTS, OEFLAG_ANIMATIONS or OEFLAG_SPRITES flags are used.

•	rMvt MUST be present if OEFLAG_MOVEMENTS is used. rMvt Must be directly after rCom

•	rAni, rSpr, and rVal are always used in this order.

 Related Topics


OEPREFS


Overview: OEPREFS
OEPREFS

OEPREFS flags control the Preferences dialog box in each editor in Click & Create. Each option controls the corresponding OEFLAG_ option in the hoOEFlag field. You can also make sure that some of your choices cannot be changed by the user. The flags available in the Preferences dialog box are:

•	 OEPREFS_BACKSAVE

•	 OEPREFS_BACKEFFECTS

•	 OEPREFS_QUICKDISPLAY

•	 OEPREFS_SCROLLINGINDEPENDANT

•	 OEPREFS_LOADONCALL

•	 OEPREFS_GLOBAL

•	 OEPREFS_SLEEP

•	 OEPREFS_KILL

If none of these flags are set, then the Preferences dialog box has no enabled options.

 Related Topics


OEPREFS_BACKSAVE

OEPREFS_BACKSAVE will enable the "Save background" option. (OEFLAG_BACKSAVE).

 Related Topics


OEPREFS_BACKEFFECTS

OEPREFS_BACKEFFECTS will enable the background erase effects option if OEPREFS_BACKSAVE is set.

 Related Topics


OEPREFS_QUICKDISPLAY

OEPREFS_QUICKDISPLAY will enable the quick display option. (OEFLAG_QUICKDISPLAY).

 Related Topics


OEPREFS_SCROLLINGINDEPENDANT

OEPREFS_SCROLLINGINDEPENDANT will enable the Follow the playfield option (OEFLAG_SCROLLINGINDEPENDANT).

 Related Topics


OEPREFS_LOADONCALL

OEPREFS_LOADONCALL will enable the load on call option.

 Related Topics


OEPREFS_GLOBAL

OEPREFS_GLOBAL will enable the "global object" option.

 Related Topics


OEPREFS_SLEEP

OEPREFS_SLEEP will enable the manual sleep options (OEFLAG_MANUALSLEEP)

 Related Topics


OEPREFS_KILL

OEPREFS_KILL will enable the Destroy if far from playfield option (OEFLAG_NEVERKILL)

 Related Topics


Examples of objects and flags


Overview: Examples of objects and flags
Examples of objects and flags

To help you find the appropriate flags for use with your extension object, here is the list of flags we have used for each of the objects in Corel Click & Create. You will find the OEFLAGS and the OEPREFS flags listed.

We have divided the objects into four sections:

•	 Objects with no output on the screen

•	 Objects opening a control on the frame window

•	 Objects opening a window on the frame window

•	 Objects drawn directly in the frame window

 Related Topics


Objects with no output on the screen

Ini object

•	OEFLAG_DISPLAYINFRONT

•	0

MCI object

•	OEFLAG_DISPLAYINFRONT

•	A

Window control object

•	OEFLAG_DISPLAYINFRONT

•	0

CD Audio object

•	OEFLAG_DISPLAYINFRONT

•	0

Print object

•	OEFLAG_DISPLAYINFRONT

•	0

Picture object

•	OEFLAG_BACKGROUND

•	0

Netscape object

•	OEFLAG_DISPLAYINFRONT

•	0

Mixer object

•	OEFLAG_DISPLAYINFRONT

•	0

ODBC object

•	OEFLAG_DISPLAYINFRONT

•	0

SEARCH object

•	OEFLAG_DISPLAYINFRONT

•	0

 Related Topics


Objects opening a control on the frame window

Button object

•	OEFLAG_WINDOWPROC | OEFLAG_DISPLAYINFRONT | OEFLAG_TABSTOP

•	OEPREFS_GLOBAL | OEPREFS_SCROLLINGINDEPENDANT

List object

•	OEFLAG_WINDOWPROC | OEFLAG_DISPLAYINFRONT | OEFLAG_TABSTOP

•	OEPREFS_GLOBAL | OEPREFS_SCROLLINGINDEPENDANT

Combo object

•	OEFLAG_WINDOWPROC | OEFLAG_DISPLAYINFRONT | OEFLAG_TABSTOP

•	OEPREFS_GLOBAL | OEPREFS_SCROLLINGINDEPENDANT

 Related Topics


Objects opening a window on the frame window

AVI object

•	OEFLAG_MOVEMENTS | OEFLAG_WINDOWPROC | OEFLAG_DISPLAYINFRONT

•	OEPREFS_GLOBAL

QTW object

•	OEFLAG_MOVEMENTS | OEFLAG_DISPLAYINFRONT

•	OEPREFS_GLOBAL

QTVR object

•	OEFLAG_DISPLAYINFRONT|OEFLAG_WINDOWPROC

•	OEPREFS_GLOBAL

MPEG object

•	OEFLAG_MOVEMENTS | OEFLAG_WINDOWPROC | OEFLAG_DISPLAYINFRONT

•	OEPREFS_GLOBAL

 Related Topics


Objects drawn directly in the frame window

FLI object

•	OEFLAG_SPRITES|OEFLAG_BACKSAVE|OEFLAG_INTERNALBACKSAVE|OEFLAG_MOVEMENTS|

OEFLAG_QUICKDISPLAY

•	OEPREFS_BACKSAVE|OEPREFS_BACKEFFECTS|OEPREFS_QUICKDISPLAY|OEPREFS_SCROLLINGINDEPENDANT|

OEPREFS_GLOBAL|OEPREFS_INKEFFECTS

Hiscore object

•	OEFLAG_SPRITES | OEFLAG_QUICKDISPLAY | OEFLAG_BACKSAVE

•	OEPREFS_GLOBAL | OEPREFS_BACKSAVE | OEPREFS_BACKEFFECTS

Clock object

•	OEFLAG_SPRITES | OEFLAG_QUICKDISPLAY | OEFLAG_BACKSAVE

•	OEPREFS_GLOBAL | OEPREFS_QUICKDISPLAY | OEPREFS_BACKSAVE | OEPREFS_BACKEFFECTS

RTF object

•	OEFLAG_SPRITES|OEFLAG_BACKSAVE|OEFLAG_INTERNALBACKSAVE|OEFLAG_QUICKDISPLAY

•	OEPREFS_SCROLLINGINDEPENDANT|OEPREFS_GLOBAL

 Related Topics


List of Necessary Routines


Overview: List of Necessary Routines
List of Necessary Routines

We have divided the necessary routines into four sections:

•	 Edition time vs. run time routines

•	 List of General Purpose routines

•	 List of edition-time routines

•	 List of run-time routines

 Related Topics


Edition time vs. run time routines

Corel Click & Create works in two main modes: edition mode and run-time mode. Use edition mode in the Frame Editor, Event editor, Step-through editor, and Time Line editor. Use the run-time mode as soon as the application starts to run.

Your extension object must also follow this logic. The code for the extension object should also be divided into two main parts: edition and run-time. The edition section should contain the Setup dialog box, the display in the frame editor, the creation of a new object, and the list of available actions and conditions. The run-time section should contain all the routines to create, animate and destroy the object, and all of the actions and conditions.

 Related Topics


List of general purpose routines

The general purpose routines are:

•	 DllMain

•	 LibMain

•	 WEP

•	 Initialize

•	 Free

•	 GetInfos

•	 GetRunObjectInfos

 Related Topics


DllMain

BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)

DLLMian is used in the 32-bit version only. This routine is the main DLL initialization routine. Please refer to Microsoft documentation for a complete explanation of this routine.

Comments

You should not use this routine to initialize resources or load data. Extension objects are frequently loaded (upon starting Corel Click & Create, and each time you open the Create new object dialog box) using a LoadLibrary call to get the icon of each object. The extensions are then freed.

Please do every initialization in the Initialize routine.

 Related Topics


LibMain

int CALLBACK LibMain(HINSTANCE hDLL, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)

LibMain is used in the 16-bit version only. This routine is the main DLL initialization routine. Please refer to Microsoft documentation for a complete explanation of this routine.

Comments

You should not use this routine to initialize resources or load data. Extension objects are frequently loaded (upon starting Corel Click & Create, and each time you open the Create new object dialog box) using a LoadLibrary call to get the icon of each object. The extensions are then freed.

Please do every initialization in the Initialize routine.

 Related Topics


WEP

int WINAPI WEP(int bSystemExit)

WEP is the 32-bit end routine. Please refer to Microsoft documentation for a complete explanation of this routine.

Comments

You should not use this routine to initialize resources or load data. Extension objects are frequently loaded (upon starting Corel Click & Create, and each time you open the Create new object dialog box) using a LoadLibrary call to get the icon of each object. The extensions are then freed.

Please do every initialization in the Free routine.

 Related Topics


Initialize

int WINAPI DLLExport Initialize(mv _far *knpV, int quiet)

The Initialize routine performs cold-start initializations.

Parameters

mv _far *knpV pointer to a knpV information structure

int quiet flag indicating whether or not to report errors.

Return value

0 if successful, -1 in case of error (the extension will not be loaded).

Comments

This routine is only called once for each object and each application, no matter how many duplicated objects are placed in any number of frames. In this routine you should perform any main initializations, like registering window classes, loading DLL's etc.

The quiet flag indicates if you can report error messages should an error occur. It also indicates if you can change the mouse pointer to a busy pointer when doing lengthy operations.

Example

Here is the initialize routine of the QuickTime object:

int WINAPI DLLExport Initialize(mv _far *knpV, int quiet)

{

HCURSOR	hCurs = 0;

// Already initialized ?

if (QuickTimeInit >= INIT_MINIMUM)

{

QuickTimeInit += INIT_MINIMUM;

return 0;

}

// Set waiting cursor

if (0 == quiet)

{

if ((hCurs = SetCursor (LoadCursor(NULL, IDC_WAIT))) != NULL)

SetCapture (knpV->mvHEditWin);

}

// Initialize Quicktime

if (0 == QuickTimeInit)

{

if (~QTInitialize(NULL))

QuickTimeInit++;	// 1

}

if (1 == QuickTimeInit)

{

if (~EnterMovies())

QuickTimeInit++; 	// 2

}

if (2 == QuickTimeInit)

{

// Register the QTW window class

wcMov.style = 0;	// Classe locale

wcMov.lpfnWndProc = (WNDPROC)WndProc;

wcMov.cbClsExtra = 0;

wcMov.cbWndExtra = 0;

wcMov.hInstance = hInstLib;

wcMov.hIcon = NULL;

wcMov.hCursor = LoadCursor(NULL, IDC_ARROW);

wcMov.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wcMov.lpszMenuName = NULL;

wcMov.lpszClassName = szMovClass;

if (RegisterClass(&wcMov) != 0)

QuickTimeInit++;	// 3

}

// Restore original cursor

if (hCurs != 0)

{

SetCursor(hCurs);

ReleaseCapture();

}

return 0;

}

 Related Topics


Free

int WINAPI DLLExport Free(mv _far *knpV)

The Free routine liberates any resources allocated by the Initialize routine.

Parameters

mv _far *knpV pointer to a knpV information structure

Return value

Should return a value of 0.

Comments

The Free routine is the counterpart of Initialize. This routine is only called once for each object and each application, no matter how many duplicated objects are placed in any number of frames. In this routine, you should free anything allocated in the cold start process.

Example

Here is the Free routine for the QuickTime object:

int WINAPI DLLExport Free(mv _far *knpV)

{

// Plus de une initialization correcte

if (QuickTimeInit > INIT_MINIMUM)

{

QuickTimeInit -= INIT_MINIMUM;

return 0;

}

if (3 == QuickTimeInit)

{

QuickTimeInit--;

UnregisterClass(szMovClass, hInstLib);

}

if (2 == QuickTimeInit)

{

QuickTimeInit--;

ExitMovies();

}

if (1 == QuickTimeInit)

{

QuickTimeInit--;

QTTerminate();

}

return 0;

}

 Related Topics


GetInfos

DWORD WINAPI DLLExport GetInfos(int info)

The GetInfos routine gives the version number of the extension.

Comments

Do not touch this routine!

 Related Topics


GetRunObjectInfos

short WINAPI DLLExport GetRunObjectInfos(mv _far *knpV, fpKpxRunInfos infoPtr)

The GetRunOjbectInfors routine returns information about run-time object flags, size of edition structures, conditions, and actions.

Parameters

mv _far *knpV pointer to a knpV information structure

fpKpxRunInfos infoPtr pointer to a KpxRunInfos structure

Returns

TRUE if OK, FALSE if an error is detected.

Comments

Use the routine given as an example; it can cope with everything, works fine, and is self-explanatory.

Example

short WINAPI DLLExport GetRunObjectInfos(mv _far *knpV, fpKpxRunInfos infoPtr)

{

infoPtr->conditions = (fpchar)ConditionJumps;

infoPtr->actions = (fpchar)ActionJumps;

infoPtr->expressions = (fpchar)ExpressionJumps;

infoPtr->numOfConditions = CND_LAST;

infoPtr->numOfActions = ACT_LAST;

infoPtr->numOfExpressions = EXP_LAST;

infoPtr->editDataSize = MAX_EDITSIZE;

infoPtr->editFlags = OEFLAGS;

// Refer to documentation

infoPtr->editPrefs = OEPREFS;

// A 4 bytes identifier, unique to this object

infoPtr->identifier = IDENTIFIER;

// The current version

infoPtr->version = KCX_CURRENT_VERSION;

return TRUE;

}

 Related Topics


Overview: List of edition time routines
List of edition time routines

The edition time routines are:

•	 UpdateEditStructure

•	 LoadObject

•	 UnloadObject

•	 UpdateFileNames

•	 DefaultOI

•	 PutObject

•	 RemoveObject

•	 MakeIcon

•	 GetDesc

•	 AppendPopup

•	 CreateObject

•	 SelectPopup

•	 ModifyObject

•	 RebuildExt

•	 EndModifyObject

•	 GetObjectCursor

•	 GetObjectRect

•	 EditorDisplay

•	 IsTransparent

•	 PrepareToWriteObject

•	 EnumElts

•	 GetConditionMenu

•	 GetActionMenu

•	 GetExpressionMenu

•	 GetConditionTitle

•	 GetActionTitle

•	 GetExpressionTitle

•	 GetConditionCodeFromMenu

•	 GetActionCodeFromMenu

•	 GetExpressionCodeFromMenu

•	 GetConditionInfos

•	 GetActionInfos

•	 GetExpressionInfos

•	 GetConditionString

•	 GetActionString

•	 GetExpressionString

 Related Topics


UpdateEditStructure

HGLOBAL WINAPI DLLExport UpdateEditStructure(mv __far *knpV, void __far * OldEdPtr)

The UpdateEditStructure routine allows you to update the versions of the edition structures.

Parameters

mv _far *knpV pointer to a knpV information structure

void __far * OldEdPtr pointer to the edition structure with the old version.

Return value

0 if the edition structure has not been changed, the handle of a newly allocated, unlocked.

Comments

Everyone makes mistakes, and this routine is here to help you correct them. The edition structure of each object is saved within the .CCA file. You might want to add new entries to it, and have them still be compatible with the applications saved before, you need to update the structures.

When the version number of the edition structure does not match the current version number of the object, Corel Click & Create calls this routine so that you can do the update process. From the old structure, you must re-create a new structure complying with your new version.

If you define more than two versions, don't forget to do an incremental update process, you never know which version of your structure may lie in an application. Therefore, for three different versions, first update from V0 to V1, then from V1 to V2 and then from V2 to V3. Doing like this ensures that whatever the version, the final structure will be correct.

Example

Here is the update routine taken from the AVI object (we had to change the pathname length and add many flags to change the code to 32-bit.)

HGLOBAL WINAPI DLLExport UpdateEditStructure(mv __far *knpV, void __far * OldEdPtr)

{

HGLOBAL	hgOld;

hgOld=0;

if (((fpedata)OldEdPtr)->eHeader.extVersion < KCX_VERSION_1)

{

HGLOBAL	hgNew;

fpedata_v1	newEdPtr;

if ((hgNew = GlobalAlloc(GPTR, sizeof(editData_v1))) != NULL)

{

newEdPtr = (fpedata_v1)GlobalLock(hgNew);

_fmemcpy(&newEdPtr->eHeader, &((fpedata_v0)OldEdPtr)->eHeader, sizeof(extHeader));

newEdPtr->eHeader.extVersion = KCX_VERSION_1;

newEdPtr->eHeader.extSize = sizeof(editData_v1);

newEdPtr->eaviIdApp = ((fpedata_v0)OldEdPtr)->eaviIdApp;

newEdPtr->eaviImage = ((fpedata_v0)OldEdPtr)->eaviImage;

newEdPtr->eaviSx = ((fpedata_v0)OldEdPtr)->eaviSx;

newEdPtr->eaviSy = ((fpedata_v0)OldEdPtr)->eaviSy;

newEdPtr->eaviFlags = ((fpedata_v0)OldEdPtr)->eaviFlags;

_fstrcpy(newEdPtr->eaviName, ((fpedata_v0)OldEdPtr)->eaviName);

_fmemcpy(newEdPtr->eaviSecu, ((fpedata_v0)OldEdPtr)->eaviSecu, 16);

hgOld = hgNew;

hgNew=0;

}

}

if (hgOld != 0)

GlobalUnlock(hgOld);

return hgOld;

}

 Related Topics


LoadObject

int WINAPI DLLExport LoadObject(mv _far *knpV, LPCSTR fileName, LPEDATA edPtr, int reserved)

The LoadObject routine is called when an object is created in the Frame editor, and at the beginning of each frame containing the object in run-time.

Parameters

mv _far *knpV pointer to a knpV information structure

LPCSTR fileName pointer to the current application pathname

LPEDATA edPtr pointer to the edition structure

int reserved reserved for future use.

Return value

0 if successful, -1 in case an error is detected.

Comments

The LoadObject routine is called once for each different object in each frame. For example, if you duplicate one object by pasting a copy anywhere in the frame, the object will still be called only once. The edPtr will point to the common edition structure of all the duplicate objects.

In this routine, you can load some data depending on the content of the edition structure, or store pointers.

Example

In the AVI object, we used this routine to grab the handle of the Corel Click & Create application:

{

edPtr->eaviIdApp = knpV->mvIdAppli;

edPtr->eaviImage = 0;

return 0;

}

 Related Topics


UnloadObject

void WINAPI DLLExport UnloadObject(mv _far *knpV, LPEDATA edPtr, int reserved)

The UnloadObject routine is called when the last object of one kind is destroyed in the Frame editor, and at the end of frames containing the object in run-time.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

int reserved reserved for future use.

Return value

None.

Comments

The UnloadObject routine is called once for each different object in each frame. For example, if you duplicate one object by pasting a copy anywhere in the frame, the object will still be called only once. The edPtr will point to the common edition structure of all the duplicate objects.

This routine will free any resources allocated in the LoadObject routine.

 Related Topics


UpdateFileNames

void WINAPI DLLExport UpdateFileNames(mv _far *knpV, LPSTR appName, LPEDATA edPtr, void (WINAPI * lpfnUpdate)(LPSTR, LPSTR))

The UpdateFileNames routine allows pathnames contained in the edition structure to be relocated by Corel Click & Create.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

void (WINAPI * lpfnUpdate)(LPSTR appName, LPSTR pathname) pointer to a function that localizes the pathname.

Return value

None.

Comments

The UpdateFileNames routine is called when every different object is loaded from each frame. This routine will call the relocation routine for every pathname contained in the edition structure. The UpdateFileNames routine ensures that the pathname is correct for the location of the application.

Example

This routine is taken from the AVI object in Corel Click & Create:

void WINAPI DLLExport UpdateFileNames(mv _far *knpV, LPSTR appName, fpedata edPtr, void (WINAPI * lpfnUpdate)(LPSTR, LPSTR))

{

// Update file name

if (edPtr->eaviName[0] != 0)

lpfnUpdate(appName, edPtr->eaviName);

}

 Related Topics


DefaultOI

void WINAPI DLLExport DefaultOI(mv _far *knpV, fpObjInfo oiPtr)

The DefaultOI routine is called when a new object is created in a frame.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to an ObjInfo structure

Return value

None.

Comments

In the DefaultOI routine, you can set flags, such as the ink effect and the save background flags, in the ObjInfo structure. Usually, you don't need to use this routine!

Example

This routine is taken from the FLI object:

void WINAPI DLLExport DefaultOI ( mv _far *knpV, fpObjInfo oiPtr )

{

oiPtr->oiPrefs = (oiPtr->oiPrefs & ~OIP_INKEFFECTMASK) | (EFFECT_OPAQUE << OIP_INKEFFECTSHIFT);

return;

}

 Related Topics


PutObject

void WINAPI DLLExport PutObject(mv _far *knpV, fpLevObj loPtr, LPEDATA edPtr, ushort cpt)

The PutObject routine is called every time an object is dropped onto the playfield of a frame.

Parameters

mv _far *knpV pointer to a knpV information structure

fpLevObj loPtr pointer to a LevelObject structure

LPEDATA edPtr pointer to the edition structure

ushort cpt number of same objects on the playfield

Return value

None.

Comments

Each time one object is dropped onto the playfield, Click & Create calls the PutObject routine. Cpt reflects the number of same objects on the frame (same objects all point to the same edition structure and the same ObjInfo structure). You might need to load some data for the first object.

Example

Actually, we never use this routine!

 Related Topics


RemoveObject

void WINAPI DLLExport RemoveObject(mv _far *knpV, fpLevObj loPtr, LPEDATA edPtr, ushort cpt)

The RemoveObject routine is called each time an object is removed (deleted) from the frame.

Parameters

mv _far *knpV pointer to a knpV information structure

fpLevObj loPtr pointer to the LevelObject structure

LPEDATA edPtr pointer to the edition structure

ushort cpt number of same objects on the playfield

Return value

None.

Comments

The RemoveObject routine is the counterpart of PutObject. Each time one object is removed from the frame, Click & Create calls the RemoveObject routine. Cpt reflects the number of same objects remaining on the frame (same objects all point to the same edition structure, and the same ObjInfo structure). Cpt=1 means you are deleting the last object and you might need to free some data.

Example

Actually, we never use this routine!

 Related Topics


MakeIcon

int WINAPI DLLExport MakeIcon ( mv _far *knpV, BITMAPINFO FAR *lpBitmap, LPSTR lpName, fpObjInfo oiPtr, LPEDATA edPtr )

The MakeIcon routine returns a bitmap with the icon to use when displaying the object in the object bar or in the Event editor.

Parameters

mv _far *knpV pointer to a knpV information structure

BITMAPINFO FAR *lpBitmap

LPSTR lpName name of the object

fpObjInfo oiPtr pointer to an ObjInfo structure

LPEDATA edPtr pointer to the edition structure

Return value

0 is OK, any value that is not 0 indicates that an error has been detected.

Comments

This function must fill the current device independent bitmap (lpBitmap). The size of this bitmap must not exceed 32 x 32 pixels. Usually, we return an icon from the resource (see examples), but you can decide to create a specific icon depending on the content of the edition structure.

This function can also change the name of the object. In this case, it should fill the lpName string (max length = OINAME_SIZE).

 Related Topics


GetDesc

void WINAPI DLLExport GetDesc(mv _far *knpV, LPSTR objStr, int cbmax, fpObjInfo oiPtr, fpLevObj loPtr, LPEDATA edPtr)

The GetDesc routine returns a string describing the object.

Parameters

mv _far *knpV pointer to a knpV information structure

LPSTR objStr destination buffer

int cbmax number of characters in the destination buffer

fpObjInfo oiPtr pointer to an ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

Return value

None.

Comments

The returned string is displayed in the status line. We usually load a string from the resource, but you can return a string created from the name of the object (found in ObjInfo structure) and the name of the extension.

Example

This routine is duplicated in all Corel Click & Create extension objects:

void WINAPI DLLExport GetDesc(mv _far *knpV, LPSTR objStr, int cbmax, fpObjInfo oiPtr, fpLevObj loPtr, LPEDATA edPtr)

{

char	*tmpStr;

if ((tmpStr = (NPSTR)LocalAlloc(LPTR, 128)) != NULL)

{

LoadString(hInstLib, M_DESC, (LPSTR)tmpStr, 127);

wsprintf(objStr, tmpStr, (LPSTR)oiPtr->oiName);

LocalFree((HLOCAL)tmpStr);

}

}

 Related Topics


AppendPopup

void WINAPI DLLExport AppendPopup(mv _far *knpV, HMENU hPopup, fpLevObj loPtr, LPEDATA edPtr, int nbSel)

The AppendPopup routine is called just before opening the pop-up menu to modify an object in the Frame editor.

Parameters

mv _far *knpV pointer to a knpV information structure

HMENU hPopup handle of the pop-up menu

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

int nbSel number of the last level 1 menu option

Return value

None.

Comments

You can add or remove options. Use DeleteMenu to remove any option you don't wish to see in the menu. The identifiers of the default entries are the following:

ID_POP_SETUP	"Setup"

ID_POP_RESIZE	"Resize Object"

ID_POP_PREFS	"Preferences"

ID_POP_NAME	"Edit Name & Icon"

ID_POP_CREATE	"Create new level object"

If you add your own entries, please use identifiers between the 2 following limits:

KPX_POP_FIRST	Base of user entries

KPX_POP_LAST	End of user entries

Example

void WINAPI DLLExport AppendPopup(mv _far *knpV, HMENU hPopup, fpLevObj loPtr, LPEDATA edPtr, int nbSel)

{

// Get rid of "View"

DeleteMenu(hPopup, 1, MF_BYPOSITION);

// Get rid of "Preferences"

DeleteMenu(hPopup, ID_POP_PREFS, MF_BYCOMMAND);

// Get rid of "New level object"

DeleteMenu(hPopup, ID_POP_CREATE, MF_BYCOMMAND);

}

 Related Topics


CreateObject

int WINAPI DLLExport CreateObject(mv _far *knpV, fpLevObj loPtr, LPEDATA edPtr)

The CreateObject routine is called when you Create a new object in the Frame editor. This function will open the Setup dialog box for each object and initialize the editing structure.

Parameters

mv _far *knpV pointer to a knpV information structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

Return value

Non-zero if the creation fails (user pressed cancel in the dialog box), 0 if the object is to be created.

Comments

Some objects don't need a new Setup dialog box when being created. In these cases, this routine sets the initialization values in the editing structure.

Example

This example is a simple call to the setup dialog box, after the size fields are initialized in the edition structure:

int WINAPI DLLExport CreateObject(mv _far *knpV, fpLevObj loPtr, LPEDATA edPtr)

{

setupParams	spa;

// Set default object flags

edPtr->sx = 32;

edPtr->sy = 32;

// Call setup

spa.edpt = edPtr;

spa.kv = knpV;

return ((int) DialOpen(hInstLib, MAKEINTRESOURCE(DB_SETUP), knpV->mvHEditWin, setupProc, 0, 0, DL_MODAL | DL_CENTER_WINDOW, (LPARAM)(LPBYTE)&spa));

}

 Related Topics


SelectPopup

int WINAPI DLLExport SelectPopup(mv _far *knpV, int menuId, fpObjInfo oiPtr, fpLevObj loPtr, LPEDATA edPtr, fpushort lpParams, int maxParams)

The SelectPopup routine is called by Click & Create when the user has selected an option in the pop-up menu that Click & Create does not automatically handle.

Parameters

mv _far *knpV pointer to a knpV information structure

int menuId identifier of chosen menu option

fpObjInfo oiPtr pointer to an ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

fpushort lpParams pointer to a communication structure reserved by Corel Click & Create

int maxParams size of the structure, in WORDs

Return value

0 if no modifications are to be done or the user has pressed cancel.

DIF_HFRAN: Click & Create calls the RebuildExt routine for each of the objects selected in the frame when the pop-up menu is opened.

KPX_MODIF_BASE: use this value as a base to define you own MODIF flags. These flags can be used later in the ModifyObject routine when the pop-up menu is opened for each of the objects selected on the frame. RebuildExt is not called if you use values above KPX_MODIF_BASE.

Comments

Depending on how much time you want to spend creating your extension object, there are two options:

•	Simple option: The setup routine directly modifies the data contained in the editing structure when the user presses OK. It returns MODIF_HFRAN and the RebuildExt routine does nothing. The simple method works fine if the user only selects one object at a time for editing, but has a side effect when the user selects more than one object — all the edition datazones are equal editing.

•	Complex option: The setup routine stores any modification done in the temporary datazone pointed to by lpParams, then performs the changes one by one in the ModifyObject routine. The main advantage of this more complex method is that when the user selects several different objects, and changes one flag in the setup dialog, only the modified flag change in all the objects — they all remain different. If you have a lot of data to store, we suggest that you reserve a datazone with GlobalAlloc and store the handle of the zone as the first parameter of the buffer pointed to by lpParams.

Note: We have used the simple option for every object except the FLI.

Example

Here is the SelectPopup routine used in the AVI object:

int WINAPI DLLExport SelectPopup(mv _far *knpV, int menuId, fpObjInfo oiPtr, fpLevObj loPtr, fpedata edPtr, fpushort lpParams, int maxParams)

{

if (ID_POP_SETUP == menuId)

{

setupParams	spa;

spa.edpt = edPtr;

spa.kv = knpV;

if (0 == DialOpen(hInstLib, MAKEINTRESOURCE(DB_SETUPAVI), knpV->mvHEditWin, aviSetupProc, 0, 0, DL_MODAL | DL_CENTER_WINDOW, (LPARAM)(LPBYTE)&spa))

return MODIF_HFRAN;

}

return 0;

}

 Related Topics


ModifyObject

int WINAPI DLLExport ModifyObject(mv _far *knpV, LPEDATA edPtr, fpObjInfo oiPtr, fpLevObj loPtr, int modif, fpushort lpParams)

The ModifyObject routine is called after the object has been edited, and when SelectPopup returns a value different than 0 and MODIF_HFRAN.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

fpObjInfo oiPtr pointer to an ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

int modif value returned by SelectPopup

fpushort lpParams pointer to a communication structure reserved by Corel Click & Create

Return value

0 if the modification was done, !=0 if any problem (the object will not be modified).

Comments

Please refer to the SelectPopup section for more information.

Any modification in the size of the object handled by Click & Create results in ModifyObject being called with MODIF_SIZE as a parameter. Your object might need to react to a modification in size.

Example

Here is the ModifyObject routine taken from the AVI object:

int WINAPI DLLExport ModifyObject(mv _far *knpV, fpedata edPtr, fpObjInfo oiPtr, fpLevObj loPtr, int modif, fpushort lpParams)

{

if (MODIF_SIZE == modif)

{

// Enable resize

if ((edPtr->eaviFlags & AVICLIP_AUTOSIZE) != 0)

{

// Enable resize

edPtr->eaviFlags ^= AVICLIP_AUTOSIZE;

// Delete previous picture

if (edPtr->eaviImage != 0)

{

DelImage(edPtr->eaviIdApp, edPtr->eaviImage);

edPtr->eaviImage = 0;

}

}

edPtr->eaviSx = lpParams[2];

edPtr->eaviSy = lpParams[3];

if (((edPtr->eaviFlags & AVICLIP_PLAYBAR) != 0) && (!((0 == edPtr->eaviName[0]) && ((edPtr->eaviFlags & AVICLIP_AUTOSIZE) != 0))))

edPtr->eaviSy -= 20;

}

return FALSE;	// error code

}

 Related Topics


RebuildExt

int WINAPI DLLExport RebuildExt(mv _far *knpV, LPEDATA edPtr, fpubyte oldExtPtr, fpObjInfo oiPtr, fpLevObj loPtr, fpushort lpParams)

The RebuildExt routine is called by Click & Create for each selected and edited object on a frame when SelectPopup returns MODIF_HFRAN.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

LPEDATA oldEdPtr pointer to the edition structure before changes

fpObjInfo oiPtr pointer to an ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

fpushort lpParams pointer to the communication structure reserved by Corel Click & Create

Return value

0 if the modification was done, !=0 if any problem (the object will not be modified)

Comments

You can use the data from the old structure and copy it in the new structure if you want. Usually we don't do anything in this routine, because all the changes are done directly in the setup dialog routine.

 Related Topics


EndModifyObject

void WINAPI DLLExport EndModifyObject(mv _far *knpV, int modif, fpushort lpParams)

The EndModifyObject routine is called by Click & Create when the modification process is over.

Parameters

mv _far *knpV pointer to a knpV information structure

int modif value returned by SelectPopup

fpushort lpParams pointer to the communication structure reserved by Corel Click & Create

Return value

None.

Comments

This routine should eventually free any memory allocated during the SelectPopup routine (the handle of which is stored in the lpParams buffer).

Example

We usually don't use this routine!

 Related Topics


GetObjectCursor

HCURSOR WINAPI DLLExport GetObjectCursor(mv _far *knpV, fpObjInfo oiPtr, fpLevObj loPtr, LPEDATA edPtr)

Get ObjectCursor is called by Corel Click & Create whenever the mouse holds the object. For example, it is called whenever you take the object from the object window, create a new object, and before you place the object on the playfield.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to an ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

Return value

The handle of the cursor to use.

Comments

The cursor is not destroyed by Click & Create. Do not use the CreateCursor function. Use the LoadCursor function instead.

Example

In this example, we want to return the normal cursor:

HCURSOR WINAPI DLLExport GetObjectCursor(mv _far *knpV, fpObjInfo oiPtr, fpLevObj loPtr, fpedata edPtr)

{

return LoadCursor(hInstLib, MAKEINTRESOURCE(EXO_CURSOR));

}

 Related Topics


GetObjectRect

void WINAPI DLLExport GetObjectRect(mv _far *knpV, RECT FAR *rc, fpLevObj loPtr, LPEDATA edPtr)

The GetObjectRect routine is called by Click & Create to find the dimensions of an object.

Parameters

mv _far *knpV pointer to a knpV information structure

RECT FAR *rc pointer to a rectangle structure where you should store the data

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

Return value

None.

Comments

Upon entry, the left and top fields of the RECT structure are set to the actual coordinates of the object. You should add the size of your object to it.

Example

In the AVI object, we retrieve the size of the icon (32x32) if no video is selected, otherwise we calculate the size depending on the chosen options:

void WINAPI DLLExport GetObjectRect(mv _far *knpV, RECT FAR *rc, fpLevObj loPtr, fpedata edPtr)

{

// Returns size of the icon

rc->right = rc->left + edPtr->eaviSx;

rc->bottom = rc->top + edPtr->eaviSy;

if (((edPtr->eaviFlags & AVICLIP_PLAYBAR) != 0) && (!((0 == edPtr->eaviName[0]) && ((edPtr->eaviFlags & AVICLIP_AUTOSIZE) != 0))))

rc->bottom += 20;

return;

}

 Related Topics


EditorDisplay

void WINAPI DLLExport EditorDisplay(mv _far *knpV, fpObjInfo oiPtr, fpLevObj loPtr, LPEDATA edPtr, RECT FAR *rc)

The EditorDisplay routine displays the object in the Frame Editor.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to the ObjInfo structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

RECT FAR *rc pointer to a RECT structure containing the position and size of the object on the frame

Return value

None.

Comments

This routine actually draws the object in the frame editor. You shouldn't draw past the limits contained in the rectangle structure. You must not use GetDC and ReleaseDC to obtain a handle to the frame window. Please refer to CNCS graphic library chapter for more information. You have the choice of using CNCS internal drawing routines or reserve a DC via CNCS and use normal Windows drawing routines.

Example

In the QTVR object, we draw a gray box with the name of the file centered in this box:

void WINAPI DLLExport EditorDisplay(mv _far *knpV, fpObjInfo oiPtr, fpLevObj loPtr, fpedata edPtr, RECT FAR *rc)

{

HBRUSH	hBrush;

POINT	point[5];

RECT	rc2;

HFONT	hFont;

npchar	strBuf;

#define	RCSIZEX	96

#define	RCSIZEY	32

// Draw box

rc->right--, rc->bottom--;

WinFillRect(knpV->mvIdEditWin, rc->left, rc->top, rc->right, rc->bottom, RGB(200, 200, 200));

WinPen(knpV->mvIdEditWin, RGB(0, 0, 0), PS_SOLID, 1);

point[0].x = rc->left;

point[0].y = rc->top;

point[1].x = rc->right;

point[1].y = rc->top;

point[2].x = rc->right;

point[2].y = rc->bottom;

point[3].x = rc->left;

point[3].y = rc->bottom;

point[4].x = rc->left;

point[4].y = rc->top;

WinLine(knpV->mvIdEditWin, (POINT _far *)point, 4);

point[0].x = rc->left;

point[0].y = rc->top;

point[1].x = rc->right;

point[1].y = rc->bottom;

WinLine(knpV->mvIdEditWin, (POINT _far *)point, 1);

point[0].x = rc->right;

point[0].y = rc->top;

point[1].x = rc->left;

point[1].y = rc->bottom;

WinLine(knpV->mvIdEditWin, (POINT _far *)point, 1);

if ((edPtr->eqtwFlags & MOVCLIP_HIDEONSTART) != 0)

{

// Hatch the windows

hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0, 0, 0));

WinGraphMode(knpV->mvIdEditWin, TRANSPARENT);

WinFillBr(knpV->mvIdEditWin, rc->left, rc->top, rc->right + 1, rc->bottom + 1, hBrush);

DeleteObject(hBrush);

// Select pen

WinPen(knpV->mvIdEditWin, RGB(0, 0, 0), PS_SOLID, 1);

// Draw a box

WinBox(knpV->mvIdEditWin, (fpBox)rc);

}

// QuickTime VR text

if (rc->right-rc->left>RCSIZEX && rc->bottom-rc->top>RCSIZEY+8)

{

rc2.left=(rc->right+rc->left-RCSIZEX)/2;

rc2.right=(rc->right+rc->left+RCSIZEX)/2;

rc2.top=rc->top+(rc->bottom-rc->top)/6-RCSIZEY;

if (rc2.top<=rc->top) rc2.top=(rc->top+rc->bottom-RCSIZEY)/2;

rc2.bottom=rc2.top+RCSIZEY;

// Un carre blanc

WinFillRect(knpV->mvIdEditWin, rc2.left, rc2.top, rc2.right, rc2.bottom, RGB(255, 255, 255));

WinPen(knpV->mvIdEditWin, RGB(0, 0, 0), PS_SOLID, 1);

WinBox(knpV->mvIdEditWin, (fpBox)&rc2);

// Le texte noir

hFont = CreateFont( - 12, 0, 0, 0, 900, 0, 0, 0,

ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" );

 if (hFont!=0)

 {

strBuf=(npchar)LocalAlloc(LPTR, 128);

if (strBuf!=0)

{

rc2.top+=10;

rc2.left+=8;

LoadString(hInstLib, M_EDITORDISPLAY, strBuf, 127);

 	WinPasteText(knpV->mvIdEditWin, hFont, &rc2, (fpchar)strBuf, RGB(0,0,0), TA_LEFT|TA_TOP);

 	LocalFree((HLOCAL)strBuf);

}

 	DeleteObject(hFont);

}

}

}

 Related Topics


IsTransparent

BOOL WINAPI DLLExport IsTransparent(mv _far *knpV, fpLevObj loPtr, LPEDATA edPtr, int dx, int dy)

The IsTransparent routine is called by Click & Create when the mouse pointer is moved over one copy of the extension object in the Frame Editor. This routine indicates whether or not the point is transparent. If the object is transparent, a mouse click will select the object beneath the transparent object.

Parameters

mv _far *knpV pointer to a knpV information structure

fpLevObj loPtr pointer to the LevelObject structure for this copy of the object

LPEDATA edPtr pointer to the edition structure

int dx X offset of the point to test relative to the left edge of the object

int dy Y offset of the point to test relative to the top edge of the object

Return value

TRUE if the point is transparent, FALSE if opaque.

Comments

Use this routine if you want to create a very precise object. We used it for sprites and bitmap based objects.

 Related Topics


PrepareToWriteObject

void WINAPI DLLExport PrepareToWriteObject(mv _far *knpV, LPEDATA edPtr, fpObjInfo oiPtr)

The PrepareToWriteObject routine is called by Click & Create prior to writing the editing structure onto disk when the application is saved.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

fpObjInfo oiPtr pointer to the ObjInfo structure

Return value

None.

Comments

You might want to clean the structure before writing it!

 Related Topics


EnumElts

int WINAPI DLLExport EnumElts (mv __far *knpV, fpedata edPtr, ENUMELTPROC enumProc, ENUMELTPROC undoProc, LPARAM lp1, LPARAM lp2)

The EnumElts routine is called by Click & Create to enumerate the CNCS images and fonts used in the extension object.

Parameters

mv _far *knpV pointer to a knpV information structure

LPEDATA edPtr pointer to the edition structure

ENUMELTPROC enumProc pointer to the enumerating function

ENUMELTPROC undoProc pointer to the undo function

LPARAM lp1 parameter to pass to the enumProc and undoProc functions

LPARAM lp2 parameter to pass to the enumProc and undoProc functions

Return value

Error code, 0 if OK. A non zero value stops enumerating.

Comments

This routine must enumerate only the images and fonts that are saved within the application. It must not enumerate temporary images and fonts. This routine is usually called when the object is being loaded or saved, and indicates to Click & Create what images and fonts to save into the application file.

For each image and font, this routine must call the enumProc function, with the following parameters:

LPWORD eltPtr	pointer to the image or font (created with one of the following CNCS 	functions: DibToImage, WinCreateFont - or the function mvEditImage).

int eltType	type: IMAGE_TAB if image, FONT_TAB if font

LPARAM lp1	parameter passed to EnumElts

LPARAM lp2	parameter passed to EnumElts

If enumProc returns an error (non zero), then you must call undoProc for each image and font already passed to enumProc.

Example

This example enumerates the 8 images and 4 fonts of an object:

int WINAPI DLLExport EnumElts (mv __far *knpV, fpedata edPtr, ENUMELTPROC enumProc, ENUMELTPROC undoProc, LPARAM lp1, LPARAM lp2)

{

int	i, j, error = FALSE;

// Enum fonts

for (i=0; i<4; i++)

{

error = enumProc (&edPtr->nFont[i], FONT_TAB, lp1, lp2);

if ( error )

{

for (j=i-1; j>=0; j--)

undoProc (&edPtr->nFont[j], IMG_TAB, lp1, lp2);

break;

}

}

// Enum images

for (i=0; i<8; i++)

{

error = enumProc(&edPtr->nImg[i], IMG_TAB, lp1, lp2);

if ( error )

{

// Undo enum images

for (j=i-1; j>=0; j--)

undoProc (&edPtr->nImg[j], IMG_TAB, lp1, lp2);

// Undo enum fonts

for (j=3; j>=0; j--)

undoProc (&edPtr->nFont, FONT_TAB, lp1, lp2);

break;

}

}

return error;

}

 Related Topics


GetConditionMenu

HMENU WINAPI DLLExport GetConditionMenu(mv _far *knpV, fpObjInfo oiPtr, LPEDATA edPtr)

The GetConditionMenu routine displays the condition pop-up menu.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to an ObjInfo structure

LPEDATA edPtr pointer to the edition structure

Return value

The menu that is to be used.

Comments

You can hide or show certain options depending on the content of the editing structure.

 Related Topics


GetActionMenu

HMENU WINAPI DLLExport GetActionMenu(mv _far *knpV, fpObjInfo oiPtr, LPEDATA edPtr)

The GetActionMenu routine displays the condition pop-up menu.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to an ObjInfo structure

LPEDATA edPtr pointer to the edition structure

Return value

The menu that is to be used.

Comments

You can hide or show certain options depending on the content of the editing structure.

 Related Topics


GetExpressionMenu

HMENU WINAPI DLLExport GetExpressionMenu(mv _far *knpV, fpObjInfo oiPtr, LPEDATA edPtr)

The GetExpressionMenu routine displays the expression pop-up menu to use.

Parameters

mv _far *knpV pointer to a knpV information structure

fpObjInfo oiPtr pointer to an ObjInfo structure

LPEDATA edPtr pointer to the edition structure

Return value

The menu that is to be used.

Comments

You can hide or show certain options depending on the content of the editing structure.

 Related Topics


GetConditionTitle

void WINAPI DLLExport GetConditionTitle(mv _far *knpV, short code, short param, fpchar strBuf, short maxLen)

The GetConditionTitle routine returns a string to be displayed when entering the condition parameters.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the selected condition

short param number of the parameter (0 or 1)

fpchar strBuf buffer to store the string, finished by a 0

short maxLen length of the buffer

Return value

None.

Comments

The GetConditionTitle routine provided in the template automatically loads the string from the resource if you define it in the array.

 Related Topics


GetActionTitle

void WINAPI DLLExport GetActionTitle(mv _far *knpV, short code, short param, fpchar strBuf, short maxLen)

The GetActionTitle routine returns a string to be displayed when entering the action parameters.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the selected action

short param number of the parameter (0 or 1)

fpchar strBuf buffer to store the string, finished by a 0

short maxLen length of the buffer

Return value

None.

Comments

The GetActionTitle routine provided in the template automatically loads the string from the resource if you define it in the array.

 Related Topics


GetExpressionTitle

void WINAPI DLLExport GetExpressionTitle(mv _far *knpV, short code, short param, fpchar strBuf, short maxLen)

The GetExpressionTitle returns a string to be displayed when entering the expression parameters.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the selected expression

short param number of the parameter (0 or 1)

fpchar strBuf buffer to store the string, finished by a 0

short maxLen length of the buffer

Return value

None.

Comments

The GetExpressionTitle routine provided in the template automatically loads the string from the resource if you define it in the array.

 Related Topics


GetConditionCodeFromMenu

short WINAPI DLLExport GetConditionCodeFromMenu(mv _far *knpV, short menuId)

The GetConditionCodeFromMenu routine converts a menu identifier from the condition pop-up menu into a condition code.

Parameters

mv _far *knpV pointer to a knpV information structure

short menuId identifier of the selected menu item

Return value

The code of the condition.

Comments

In the template provided, the menu identifier is defined to directly reflect the condition codes.

 Related Topics


GetActionCodeFromMenu

short WINAPI DLLExport GetActionCodeFromMenu(mv _far *knpV, short menuId)

The GetActionCodeFrom Menu routine converts a menu identifier from the action pop-up menu into a action code.

Parameters

mv _far *knpV pointer to a knpV information structure

short menuId identifier of the selected menu item

Return value

The code of the action.

Comments

In the template provided, menu identifier is defined to directly reflect the condition codes.

 Related Topics


GetExpressionCodeFromMenu

short WINAPI DLLExport GetExpressionCodeFromMenu(mv _far *knpV, short menuId)

The GetExpressionCodeFromMenu routine converts a menu identifier from the expression pop-up menu into an expression code.

Parameters

mv _far *knpV pointer to a knpV information structure

short menuId identifier of the selected menu item

Return value

The code of the expression.

Comments

In the template provided, menu identifier is defined to directly reflect the expression codes.

 Related Topics


GetConditionInfos

infosEvents _far * WINAPI DLLExport GetConditionInfos(mv _far *knpV, short code)

The GetConditionInfos routine returns a pointer to an infosEvents structure from a condition code. The pointer is relative to this code.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the condition

Return value

Pointer to an infoEvents structure.

Comments

In the template provided, the condition codes are sorted from 0 upward. The infoEvents array, defined at the beginning of the code, is sorted in the same order. This helps to make this routine very simple and easy to use.

 Related Topics


GetActionInfos

infosEvents _far * WINAPI DLLExport GetActionInfos(mv _far *knpV, short code)

The GetActionInfos routine returns a pointer to an infosEvents structure from an action code. The pointer is relative to this code.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the action

Return value

Pointer to an infoEvents structure.

Comments

In the template provided, the action codes are sorted from 0 upward. The infoEvents array, defined at the beginning of the code, is sorted in the same order. This helps to make this routine very simple and easy to use.

 Related Topics


GetExpressionInfos

infosEvents _far * WINAPI DLLExport GetExpressionInfos(mv _far *knpV, short code)

The GetExpressionInfos routine returns a pointer to an infosEvents structure from an expression code. The pointer is relative to this code.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the expression

Return value

Pointer to an infoEvents structure.

Comments

In the template provided, the action codes are sorted from 0 upward. The infoEvents array, defined at the beginning of the code, is sorted in the same order. This helps to make this routine very simple and easy to use.

 Related Topics


GetConditionString

void WINAPI DLLExport GetConditionString(mv _far *knpV, short code, fpchar strPtr, short maxLen)

The GetConditionString routine returns the display string, from a condition code, to use in the Event Editor.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the condition

fpchar strPtr buffer to store the string, ended by 0

short maxLen length of the buffer

Return value

None.

Comments

In the template provided, all the strings in the resource are sorted in the same order as the code of the conditions. This routine just performs a LoadString into the buffer. We recommend that you leave the routine like this!

 Related Topics


GetActionString

void WINAPI DLLExport GetActionString(mv _far *knpV, short code, fpchar strPtr, short maxLen)

The GetActionString routine returns the display string, from an action code, to use in the Event Editor.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the action

fpchar strPtr buffer to store the string, ended by 0

short maxLen length of the buffer

Return value

None.

Comments

In the template provided, all the strings in the resource are sorted in the same order as the code of the conditions. This routine just performs a LoadString into the buffer. We recommend that you leave the routine like this!

 Related Topics


GetExpressionString

void WINAPI DLLExport GetExpressionString(mv _far *knpV, short code, fpchar strPtr, short maxLen)

The GetExpressionString routine returns the display string, from an expression code, to use in the Event Editor.

Parameters

mv _far *knpV pointer to a knpV information structure

short code code of the expression

fpchar strPtr buffer to store the string, ended by 0

short maxLen length of the buffer

Return value

None.

Comments

In the template provided, all the strings in the resource are sorted in the same order as the code of the conditions. This routine just performs a LoadString into the buffer. We recommend that you leave the routine like this!

 Related Topics


Overview: List of run-time routines
List of run-time routines

The run-time routines include:

•	 GetRunObjectDataSize

•	 CreateRunObject

•	 DestroyRunObject

•	 HandleRunObject

•	 GetImageInfosRunObject

•	 DisplayRunObject

•	 ReInitRunObject

•	 PauseRunObject

•	 ContinueRunObject

•	 ChangeRunData

•	 RestoreBackground

•	 SaveBackground

•	 WindowProc

•	 KillBackground

 Related Topics


GetRunObjectDataSize

ushort WINAPI DLLExport GetRunObjectDataSize(fprh rhPtr, LPEDATA edPtr)

The GetRunObjectDataSize routine returns the size of the run-time structure.

Parameters

fprh rhPtr pointer to Corel Click & Create main run-time structure

LPEDATA edPtr pointer to the extension edition-time structure

Returns

This routine should return the exact size that your object will need to work.

Comments

This routine is called just before the object is created. Usually, one returns the size of the run-time structure RUNDATA, but you might need to have a different value to store strings or arrays of values.

Because all of the object data zones are stored in one buffer, you should not ask for too much space: 1 or 2K as a maximum. If you need more memory, you can allocate it in CreateRunObject and free it in DestroyRunObject.

 Related Topics


CreateRunObject

short WINAPI DLLExport CreateRunObject(LPRDATA rdPtr, LPEDATA edPtr, fpcob cobPtr)

The CreateRunObject routine creates the object in run-time.

Parameters

LPRDATA rdPtr pointer to the run-time object structure freshly reserved by Corel Click & Create. This structure is always set to zero.

LPEDATA edPtr pointer to the object edition structure

fpcob cobPtr pointer to a CreateObject structure

Returns

0 if the creation successful, !=0 if failed.

Comments

This routine is called only once for each object. Memory allocations, that will have to be destroyed in the DestroyRunObject function, can be performed safely

CreateRunObject forms the link between the editing structure EDITDATA and the run-time structure RUNDATA. You should copy all the necessary elements from the editing structure to the run-time structure in this function. You won't have access to the editing structure while the application is running.

For the most part, you are free to do whatever you want in this routine. However, you cannot write on the screen using this routine. Any graphic operations must be done in the DisplayRunObject routine.

If CreateRunObject fails, the DestroyRunObject function is called anyway.

If you don't define the GetImageInfosRunObject routine, you must set the fields rdPtr->rHo.hoImgWidth, rdPtr->rHo.hoImgHeight, rdPtr->rHo.hoImgXSpot and rdPtr->rHo.hoImgYSpot of your object to obtain a correct display.

 Related Topics


DestroyRunObject

short WINAPI DLLExport DestroyRunObject(LPRDATA rdPtr, long fast)

The DestroyRunObject routine destroys an object during run-time.

Parameters

LPRDATA rdPtr pointer to run-time object structure

long fast flag that indicates the destruction mode.

•	Slow (0) is used in the middle of the application. The object will be completely removed after two cycles so that it's properly erased from the screen.

•	Fast (1) is used for critical times when you don't need to worry about erasing the screen.

Returns

This function should always return 0.

Comments

Don't worry about the fast flag, it's handled automatically by Click & Create. This routine should delete any memory allocated during the life of the object and leave the place as clean as it was before the object was created.

This routine is called only once for each object. It is also called if the CreateRunObject cannot create the object.

 Related Topics


HandleRunObject

short WINAPI DLLExport HandleRunObject(LPRDATA rdPtr)

The HandleRunObject routine is called every 1/50 of a second when the application runs. This routine handles every task that the object performs.

Parameters

LPRDATA rdPtr pointer to the run-time structure.

Returns

Can return a value consisting of one or more of the following flags:

•	REFLAG_ONESHOT Indicates that the routine must not be called any more.

•	REFLAG_DISPLAY Indicates that the DisplayRunObject routine should be called.

Comments

REFLAG_ONESHOT flag is generally used for objects where the HandleRunObject routine does nothing, and thus saves processing time for the application. You should not use this flag with a object defined with the OEFLAG_MOVEMENT flags (an object that has a movement). Once removed from the calling list, the HandleRunObject routine can be re-inserted (for example by an action that modifies the object) by using the sequence: callRun-timeFunction(rdPtr, RFUNCTION_REHANDLE, 0, 0);

HandleRunObject should not write anything to the screen. To write anything to the screen, use you should use the DisplayRunObject routine. Use HandleRunObject to indicate to Click & Create that the Display routine should be called using the REFLAG_DISPLAY flag. If you don't use this flag, and if the object doesn't move, the display routine will never be called. You may want to use this feature for objects that actually don't display anything, like the INI object. Another way to force a redisplay from an action routine, is to call: callRun-timeFunction(rdPtr, RFUNCTION_REDRAW, 0, 0);

 Related Topics


GetImageInfosRunObject

short WINAPI DLLExport GetImageInfosRunObject (LPRDATA rdPtr)

The GetImageInfosRunObject routine calculates the current size of the object for background saving.

Parameters

LPRDATA rdPtr pointer to the run-time structure

Returns

Should return TRUE.

Comments

You only need to use this routine if the size and hot spots of your object change. If defined, this routine is called just before the background saving process, and must update the fields rdPtr->rHo.hoImgWidth, rdPtr->rHo.hoImgHeight, rdPtr->rHo.hoImgXSpot and rdPtr->rHo.hoImgYSpot in the object’s run-time datazone to the current size. These values are immediately used (as well as rdPtr->rHo.hoX, rdPtr->rHo.hoY) to calculate the area of the screen to save in a buffer.

 Related Topics


DisplayRunObject

short WINAPI DLLExport DisplayRunObject(LPRDATA rdPtr)

The DisplayRunObject routine draws the object on the screen.

Parameters

LPRDATA rdPtr: pointer to run-time structure.

Returns

This function should return 0.

Comments

DisplayRunObject is the only routine that will draw objects on the screen, save or restore backgrounds, and respect the priority of the objects.

You will find more information on how to draw on the Click & Create screen using CNCS.DLL function in this help file. You cannot use Windows GetDC and ReleaseDC for this.

If your object is not actually drawn in the screen, but is a window for example, you should use the DisplayRunObject function to change the window size and position. These parameters should not be changed in the middle of the action routines.

 Related Topics


ReInitRunObject

short WINAPI DLLExport ReInitRunObject(LPRDATA rdPtr)

The RInitRunObject routine is used to reinitialize an object after the fade-in process.

Parameters

LPRDATA rdPtr: pointer to run-time structure.

Returns

Should return 0 if it succeeds, –1 otherwise.

Comments

This routine is only used if the flag OEFLAG_RUNBEFOREFADEIN is set in the object preferences. If this is the case, the object is created just before the fade-in, one loop of the application is run, the application datazone is pushed in memory, and the fade-in is run. At the end of the routine, the old datazone is restored and reInit routines of the created object is called. Then, only objects that don't contain the flag OEFLAG_RUNBEFOREFADEIN are created.

Usually, only objects that draw themselves directly onto the screen should be created before the fade-in.

 Related Topics


PauseRunObject

short WINAPI DLLExport PauseRunObject(LPRDATA rdPtr)

The PauseRunObject routine temporary stops the object when the application enters pause mode.

Parameters

LPRDATA rdPtr: pointer to run-time structure.

Returns

Should return 0.

Comments

There are several ways to enter pause mode:

•	the user presses CONTROL + P

•	the application is launched using the Play button, and then stopped using the PAUSE button

•	the Step-though Editor is called

The address of the datazone can be changed depending on the editing process (the ChangeRunData routine is called).

 Related Topics


ContinueRunObject

short WINAPI DLLExport ContinueRunObject(LPRDATA rdPtr)

The ContinueRunObject routine restarts the object after a pause.

Parameters

LPRDATA rdPtr: pointer to run-time structure.

Returns

Should return 0.

Comments

The ContinueRunObject routine is called when the user ends the pause mode, by pressing the PLAY button in the editor, or when the user exits the Step-through editor.

 Related Topics


ChangeRunData

short WINAPI DLLExport ChangeRunData(LPRDATA rdOld, LPRDATA rdNew)

The ChangeRunData routine indicates that the address of the run-time datazone has changed.

Parameters

LPRDATA rdOld: pointer to old run-time structure.

LPRDATA rdNew: pointer to new run-time structure.

Returns

This routine should return 0.

Comments

Corel Click & Create re-allocates the buffer containing the object datazone each time you restart an application after a pause. Therefore, the address of the object run-time structure is changed. If you store the address of the datazone somewhere within your extension object, you must update them to the new address to avoid crashes.

 Related Topics


RestoreBackground

short WINAPI DLLExport RestoreBackground ( fprdata rdPtr )

The RestoreBackground routine restores the screen to what looked like before the object was drawn.

Parameters

LPRDATA rdPtr pointer to the run-time structure.

Returns

Should return 0.

Comments

This routine is only called if the flags OEFLAG_BACKSAVE and OEFLAG_INTERNALBACKSAVE are set.

This routine checks that a memory buffer has been reserved in a previous loop. If it has, the portion of the screen saved by it is restored.

Warning: the hoX and hoY files contain the new coordinates of the object, therefore you must save the coordinates as well as the portion of the screen.

Example

Here is an example of the RestoreBackground routine, taken from the RTF object:

short WINAPI DLLExport RestoreBackground ( fprdata rdPtr )

{

fprh	rhPtr;

LPVOID	tmpPtr;

if ( rdPtr->rHo.hoHgBack != NULL )

{

rhPtr = rdPtr->rHo.hoAdRunHeader;

tmpPtr = &rdPtr->rHo.hoHgBack;

RestoreRect (rhPtr->rhIdEditWin, (WORD)FP_SEG(tmpPtr), (DWORD)(FP_OFF(tmpPtr)));

}

return 0;

}

 Related Topics


SaveBackground

short WINAPI DLLExport SaveBackground ( fprdata rdPtr )

The SaveBackground routine saves the screen area of the object in a memory buffer.

Parameters

LPRDATA rdPtr pointer to the run-time structure

Returns

Should return 0.

Comments

This routine is only called if the flags OEFLAG_BACKSAVE and OEFLAG_INTERNALBACKSAVE are set. If these two flags are set, before any call to DisplayRunObject, Click & Create calls the SaveBackground routine. In this routine you should reserve a memory buffer big enough to contain the portion of the screen covered by your object, and copy the content of the area into this routine.

Example

Here is an example of the SaveBackground routine, taken from the RTF object:

short WINAPI DLLExport SaveBackground ( fprdata rdPtr )

{

fprh	rhPtr;

LPVOID	tmpPtr;

if ( rdPtr->rHo.hoHgBack == NULL )

{

rhPtr = rdPtr->rHo.hoAdRunHeader;

tmpPtr = &rdPtr->rHo.hoHgBack;

SaveRect (rhPtr->rhIdEditWin,

 (WORD)FP_SEG(tmpPtr), (DWORD)(FP_OFF(tmpPtr)),

 (short)(rdPtr->rHo.hoX-rhPtr->rhWindowX),

 (short)(rdPtr->rHo.hoY-rhPtr->rhWindowY),

 (short)(rdPtr->rHo.hoX-rhPtr->rhWindowX+rdPtr->rHo.hoImgWidth),

 (short)(rdPtr->rHo.hoY-rhPtr->rhWindowY+rdPtr->rHo.hoImgHeight));

}

return 0;

}

 Related Topics


WindowProc

LRESULT CALLBACK DLLExport WindowProc(fprh rhPtr, HWND hWnd, UINT msgType, WPARAM wParam, LPARAM lParam)

When the OEFLAG_WINDOWPROC flag is set, Corel Click & Create calls the WindowProc routine before calling the frame-window handling procedure.

Parameters

fprh rhPtr pointer to Corel Click & Create may run-time structure, RunHeader.

HWND hWnd window handle, as defined by Microsoft.

UINT msgType Microsoft default parameter for window procedure.

WPARAM wParam Microsoft default parameter for window procedure.

LPARAM lParam Microsoft default parameter for window procedure.

Return value

0: message was not touched, and should be carried up to the frame window procedure.

REFLAG_MSGHANDLED: the message stops immediately, and returns a value of 0L to Windows.

REFLAG_MSGCATCHED: the message is not sent to any extension object, but still carry on to the frame-window procedure.

REFLAG_MSGRETURNVALUE: the WindowProc routine stores longword data in the field: rhPtr->rh4.rh4KpxReturn. Corel Click & Create returns this value to a Window with a return rhPtr->rh4.rh4KpxReturn.

REFLAG_MSGDEFPROC: Corel Click & Create calls the default window handling procedure, with return DefMsgProc (hWin, msg, wParam, lParam).

Comments

The OEFLAG_WINDOWPROC routine is only called if the OEFLAG_WINDOWPROC flag is set. If you open a control window as a child object of the frame window and wish to handle notification messages in the WindowProc procedure, we suggest to install Corel Click & Create hook (see How to control a window from an extension) so that you can easily recover the address of the RUNDATA structure controlling this window from the handle.

The routine checks the status of the pause and should not respond to every message if the application is paused:

// If pause, out

if (rhPtr->rh2.rh2PauseCompteur != 0)return 0;

For example, in pause mode, the extension should respond to palette messages, but not to WM_COMMAND or CLICK messages.

Examples

You will find plenty of examples of the WindowProc routine in the EDIT and WINDOWS.C sources in the extension kit.

 Related Topics


KillBackground

short WINAPI DLLExport KillBackground ( fprdata rdPtr )

The KillBackground routine destroys the memory buffer used to save the screen area behind the object.

Parameters

LPRDATA rdPtr pointer to the run-time structure.

Returns

Should return 0.

Comments

This routine is only called if the flags OEFLAG_BACKSAVE and OEFLAG_INTERNALBACKSAVE are set. This routine checks that a memory zone is actually reserved, and only then should this memory zone be destroyed.

Example

Here is an example of routine, taken from the RTF object:

short WINAPI DLLExport KillBackground ( fprdata rdPtr )

{

if ( rdPtr->rHo.hoHgBack != NULL )

{

GlobalUnlock (rdPtr->rHo.hoHgBack);

GlobalFree (rdPtr->rHo.hoHgBack);

rdPtr->rHo.hoHgBack = NULL;

}

return 0;

}

 Related Topics


Actions, conditions and expressions


Overview: Actions, conditions and expressions
Actions, conditions and expressions

Actions, conditions, and expressions are the keys to the power of your extension object. Actions, conditions, and expressions give the user complete control over the object that you have created. By carefully choosing the conditions and actions, you multiply the possibilities of using your object.

It's very simple to define a new condition or action, simply follow the step by step guide:

•	 The condition routine

•	 The action routine

•	 The expression routine

•	 Conditions and Actions in resource files

•	 Expressions in resource files

•	 Condition flags, true and false events

•	 Condition-only parameters

•	 Action and condition parameters

•	 Expression-only parameters

 Related Topics


The condition routine

long WINAPI DLLExport Condition(LPRDATA rdPtr, long param1, long param2)

Each condition you define must have its own routine. This routine is called by Click & Create when the condition needs evaluation.

Parameters

LPRDATA rdPtr pointer to the run-time object structure

long param1 first parameter if necessary

long param2 second parameter, if necessary

Return value

FALSE if the condition is not satisfied, TRUE if it is. If one of the parameters is PARAM_COMPARAISON or PARAM_CMPSTRING, then the return value must be the value to compare with.

Comments

This routine should be as fast as possible because it can be called quite often while the application is running.

Param1 and param2 are only defined if you specify a parameter in the eventInfos array at the beginning of the source code. Each routine should have a pointer to itself in the ConditionJumps array.

Examples

This example routine is taken from the Edit objects "Is Visible?" condition:

long WINAPI DLLExport IsVisible(fprdata rdPtr, long param1, long param2)

{

if ((rdPtr->hWnd != NULL) && (rdPtr->sVisible != 0))

return TRUE;

else

return FALSE;

}

This example is taken from the AVI object. This routine handles a true event (the flag EVFLAGS_ALWAYS is not used in the condition definition) in the "User clicks within video" condition. In this example, information must be stored about the condition in the RUNDATA structure so that the routine can recover it when called.

long WINAPI DLLExport Click(fprdata rdPtr, long param1, long param2)

{

fprh	rhPtr;

rhPtr = rdPtr->rHo.hoAdRunHeader;

if (rhPtr->rh4.rh4EventCount == rdPtr->raviClickCount)

{

if (rdPtr->raviClick == param1)

{

rdPtr->raviClick = 0;

return TRUE;

}

}

return FALSE;

}

When the user clicks inside the AVI, the AVI object stores the number of the loop where the click occurred, in rdPtr->raviClickCount and generates an event using the appropriate function. Then Click & Create calls the condition routine. It then checks the number of the current loop to the number of the loop stored in the RUNDATA to ensure it's in the correct loop number.

 Related Topics


The action routine

short WINAPI DLLExport Action(LPRDATA rdPtr, long param1, long param2)

Each action you define for your extension object must have its own action routine. This routine is called by Click & Create when an action is being executed by the application.

Parameters

LPRDATA rdPtr pointer to the run-time object structure

long param1 first parameter if necessary

long param2 second parameter, if necessary

Return value

Should return 0.

Comments

Make your action routine as fast as possible because it can be called often during the running of the application.

Param1 and param2 are only defined if you specify a parameter in the eventInfos array at the beginning of the source.

Each routine should have a pointer to itself in the ActionJumps array.

An action routine is not allowed to draw anything on the screen. What it should do is enforce a redraw process of the object so that, when the application advances to the next screen and it's refreshed, the DisplayRunObject routine gets called. callRun-timeFunction(rdPtr, RFUNCTION_REDRAW, 0, 0) does this job for you.

Example

The following code is from the "Set horizontal size" routine for the QTVR object. You can see that it only stores the new size and enforces a redraw event if the QTVR is displayed in its own window. Using this method, you can change the real window size once, in both the X and Y directions.

short WINAPI DLLExport SetXSize(fprdata rdPtr, long param1, long param2)

{

if (rdPtr->hwndMov != NULL)

{

if (param1 > 0)

{

rdPtr->rHo.hoImgWidth = (short)param1;

rdPtr->rcMovie.right = (int)param1;

callRun-timeFunction(rdPtr, RFUNCTION_REDRAW, 0, 0);

}

else

rdPtr->rqtwError = -1;

}

else

rdPtr->rqtwError = -1;

return 0;

}

 Related Topics


The expression routine

long WINAPI DLLExport Expression(LPRDATA rdPtr,long param1)

Each expression you define for your extension object must have its own expression routine. This routine is called by Click & Create when the expression needs evaluation.

Parameters

LPRDATA rdPtr pointer to the run-time object structure

long param1 first parameter information, if necessary

Return value

If the expression is a numeric expression, the expression routine should return the long value of the calculation. If the expression is a string expression, it should return a pointer to the calculated string or a zero endWarning.

Note: The size of the string should not exceed 1024 bytes.

Comments

Make your expression routine as fast as possible because it can be called often during the running of the application.

To get the parameters, you must use the following routines, in this order:

// Gets parameters 1 and 2

l1=callRun-timeFunction(rdPtr, RFUNCTION_GETPARAM1, 0, param1);

l2=callRun-timeFunction(rdPtr, RFUNCTION_GETPARAM2, 0, param1);

For one parameter, use the first line only.

Example

This example routine was taken from the EDIT object. This example handles the =number expression:

long WINAPI DLLExport GetValue(fprdata rdPtr, long param1)

{

npchar	strBuf;

long	l;

strBuf=(npchar)LocalAlloc(LPTR, 40);

if (strBuf!=0)

{

GetWindowText(rdPtr->hWnd, strBuf, 39);

l=atol(strBuf);

LocalFree((HLOCAL)strBuf);

}

return l;

}

This example was also taken from the EDIT object. This routine is used to return the current edition string:

long WINAPI DLLExport GetText(fprdata rdPtr, long param1)

{

UINT	uiTextSize;

void _huge*	buffer;

// Free memory

if (rdPtr->hglb != NULL)

{

GlobalUnlock(rdPtr->hglb);

GlobalFree(rdPtr->hglb);

rdPtr->hglb = NULL;

}

// Get text size

uiTextSize = min(GetWindowTextLength(rdPtr->hWnd) + 1, 1024);

// Alloc memory

if ((rdPtr->hglb = GlobalAlloc(GPTR, uiTextSize)) != NULL)

{

// Lock mem

buffer = GlobalLock(rdPtr->hglb);

// Get text

GetWindowText(rdPtr->hWnd, buffer, uiTextSize);

// Return pointer

rdPtr->rHo.hoFlags |= HOF_STRING;

return (long)buffer;

}

// ok

return (long)(LPCSTR)szNullString;

}

 Related Topics


Conditions and actions in resource files

For every action or condition you assign to your extension object, you must define the following:

•	A menu entry in the action condition pop-up menu

•	A display string so that Click & Create can display the actions or conditions in the Event editor list

It's easy to add a menu entry in the action condition pop-up menu. Use a normal menu option in a normal Windows pop-up menu.

Displaying a string so that Click & Create can display the actions or conditions in the event editor list is a little more complex because Click & Create must insert the eventual parameters and the object's icon when displaying it in the Event Editor. The Click & Create system was designed to cope with all the possibilities of combining one string (the condition/action string), the name of the object, and the parameters (either 0, 1, or 2).

We used the wsprintf function, with %s characters within the string. We needed to indicate what to insert and where to insert the different elements in the string. To do this, we used a code consisting of two numbers at the beginning of each display string.

The display string has to follow the rule:

"XYMy condition text [%s][%s][%s]"

X: this number should be 0 or 1.

•	0: no object name is to be put in the string. For example, "Timer equals xxx", the word timer is already in the string, so there is no need to replace it by anything.

•	1: means that the FIRST occurrence of %s will be replaced by the name of the object.

•	2: means that the second %s from the string will be replaced by the name of the object.

•	3: means the third %s will be replaced.

Y: this number can be 0, 1, or 2.

•	0: means that no parameters are used for this string.

•	1: means that the remaining %s (after the eventual replacement of one %s by the name of the object) are replaced by the parameters, replacing the order of the parameters (as coded in the program).

•	2: means that the remaining %s are to be replaced by the parameters, but this time, the order of the parameters will be swapped.

As you can see, the two numbers at the beginning of the string can code any possible combination.

Example 1:

"01Number of objects in %s %s"

With the first parameter being a zone parameter, and the second a comparison, give when displayed:

"Number of objects in zone(0,0) to (10,10)=15"

Example 2:

"11%s is facing a direction %s"

Original string in program gives:

Romeo is facing a direction south

Change 11 into 21, you get:

south is facing a direction Romeo

Example 3:

"11Number of %s in %s %s"

Original:

Number of Romeo in zone () to () = 10

Change 11 to 21:

Number of zone() to () in Romeo = 10

Change 11 to 31:

Number of zone() to () in =10 Romeo

Change 11 to 12:

Number of Romeo in =10 zone() to ()

Change 11 to 22:

Number of =10 in Romeo zone() to ()

Change 11 to 32:

Number of =10 in zone() to () Romeo

Have a look at the resources of the example object in the Edit, Clock, and INI folders.

 Related Topics


Expressions in resource files

Expressions, just like conditions and actions, need two strings in the resource file:

•	A menu entry in the expression pop-up menu

•	A display string so that Click & Create can list the expression in the Event Editor

It's easy to add a menu entry in the expression pop-up menu. Use a normal menu option in a normal Windows pop-up menu, and explain as briefly as possible what your expression returns.

To display a string so that Click & Create can display the expression is the expression token. It must be unique for this object because the expression evaluator matches the string entered by the user and the strings found in the different objects resources until it finds the correct one. It must not contain more than 20 characters, and must finish with an opened bracket.

Examples, from the Clock object:

"seconds of("

"minutes of("

"hours of("

"day of week of("

All the above expressions return a numeric value. To indicate that your expression returns a string, you should put a dollar sign before the bracket.

Example of string expression from the system object:

"str$("

Inserting a dollar sign before the bracket is the only indication that your expression returns a string.

 Related Topics


Condition flags, true and false events

If you inspect the source code of the Edit, Clock, or INI objects, you will notice some in the conditionsInfos array at the beginning of the file, EVFLAGS_ALWAYS or EVFLAGS_NOTABLE. These flags are very important because they define the behavior of each condition.

True and false event-driven conditions.

Click & Create can handle two different types of conditions: evenemental and non-evenemental conditions.

•	Truly evenemental conditions rely on a true event, such as a mouse click, a collision, a keyboard key being pressed, or a menu option being chosen. Let's take the example of the mouse click: the user clicks somewhere in the frame, Click & Create receives the click message, and then explores the list of events to see if a condition dealing with the click exists as the first condition in a group of events. If yes, then this condition is evaluated, and if the result of the evaluation is TRUE, the other (eventual) conditions of the group of events are evaluated. A condition that is truly evenemental and the first condition in a group of conditions, is evaluated really fast because it is evaluated only when the event actually occurs.

•	Non-evenemental conditions usually involve a comparison, such as Global Value 1<10, and aren't triggered by a true event. Click & Create evaluates these conditions at each loop of the application A condition can also be non-evenemental when a truly-evenemental condition is located at position 2 (or higher) in a group of conditions list. In this case, Click & Create calls the evaluation routine when necessary.

So what should you do?

If your condition is going to respond to a mouse click or another very specific event, then you should make it truly evenemental. If not, it should be evaluated at each loop. The flags that can be used are:

•	EVFLAGS_ALWAYS: tells Click & Create that the condition should be evaluated at each loop. If you inspect the source code, you will see that this is the case for most of the conditions in the example objects.

•	No EVFLAGS_ALWAYS: tells Click & Create that your condition will only be evaluated if an event is generated (by you, using the RFUNCTION_GENERATEEVENT, RFUNCTION_PUSHEVENT or RFUNCTION_PUSHEVENTSTOP functions) if it's the first one of a group of events, or when needed if it's not the first one of a group of event.

•	In the case of a non-evenemental condition, you can also add the flag:

•	EVFLAGS_NOTABLE: indicates that your condition can be inverted. In this case, the Negate option will be available when you click the condition with the right mouse button.

Examples

Here is an example of a non-evenemental condition definition and routine taken from the clock object:

The definition:

{CND_VISIBLE,EVFLAGS_ALWAYS+EVFLAGS_NOTABLE,0,0,0,0},

The routine:

long WINAPI DLLExport IsVisible(fprdata rdPtr, long param1, long param2)

{

if (TRUE == rdPtr->sVisible)

return TRUE;

else

return FALSE;

}

As you can see, this condition can be negated and is called at every loop.

Here is evenemental condition definition and its routine, taken from the AVI object:

The definition:

{CND_CLICK,0,PARAM_CLICK,0,0, 0},

Where the event is generated (in window-handling procedure):

LRESULT WINAPI DLLExport WndProc(fprh rhPtr, HWND hDlg, uint msgType, WPARAM wParam, LPARAM lParam)

{

fprdata	rdPtr;

short	p;

// Process messages

switch (msgType)

{

case WM_LBUTTONDOWN:

p = 0;

goto WndProc_suite;

case WM_MBUTTONDOWN:

p = 1;

goto WndProc_suite;

case WM_RBUTTONDOWN:

p = 2;

goto WndProc_suite;

case WM_LBUTTONDBLCLK:

p = 0 + PARAMCLICK_DOUBLE;

goto WndProc_suite;

case WM_MBUTTONDBLCLK:

p = 1 + PARAMCLICK_DOUBLE;

goto WndProc_suite;

case WM_RBUTTONDBLCLK:

p = 2 + PARAMCLICK_DOUBLE;

WndProc_suite:

rdPtr=GetRdPtr(hDlg, rhPtr);

if (0 == rhPtr->rh2.rh2PauseCompteur && rdPtr!=0)

{

// Store for non-evenmental calls

rdPtr->raviClick = p;

rdPtr->raviClickCount = rhPtr->rh4.rh4EventCount;

// Generates the event

callRun-timeFunction(rdPtr, RFUNCTION_GENERATEEVENT, CND_CLICK, 0);

}

break;

}

return 0L;

}

You can see that the routine detects the click messages sent by Windows and creates a PARAM_CLICK parameter. The number of the loop where the click actually occurred is stored in the RUNDATA structure and the CND_CLICK event is generated.

The routine:

long WINAPI DLLExport Click(fprdata rdPtr, long param1, long param2)

{

fprh	rhPtr;

rhPtr = rdPtr->rHo.hoAdRunHeader;

if (rhPtr->rh4.rh4EventCount == rdPtr->raviClickCount)

{

if (rdPtr->raviClick == param1)

{

rdPtr->raviClick = 0;

return TRUE;

}

}

return FALSE;

}

The above routine works if the condition was generated as either a truly evenemental condition or a non-evenemental condition. In both cases, this routine compares the number of the current loop to the number of the loop stored in the RUNDATA structure, if they match (means that the click just occurred), it compares the PARAM_CLICK parameter of the condition to the one generated from the user input. If they match, (meaning the user clicked with the correct mouse button), then this function returns TRUE.

 Related Topics


Condition-only parameters

The Condition-only parameters are:

•	 PARAM_COMPARAISON

•	 PARAM_CMPTIME

•	 PARAM_CMPSTRING

 Related Topics


PARAM_COMPARAISON

What is the user asked?

The user is asked to enter a comparison consisting of both an expression and a comparison operator. This parameter is only valid for conditions.

Value entering the action/condition routine

Your condition routine doesn't have to do the comparison itself, Click & Create handles the comparison automatically. This routine shouldn't return a value of true or false, but rather a long value to be compared to the value entered by the user. Therefore, the value of the parameter you get by entering the condition routine has no purpose.

Example

This routine is for the "Compare to current number of frame" condition. You can see that this routine doesn't perform the comparison, it simply returns the value to compare with.

long WINAPI DLLExport Cnd_CompareFrame (fprdata rdPtr, long param1, long param2)

{

if ( rdPtr->rFifo.flFrame == 0 )

return 1L;

if ( rdPtr->rFifo.flFrame > rdPtr->rFifo.flHeader.fhFrames )

return (DWORD)rdPtr->rFifo.flHeader.fhFrames;

return (DWORD)(rdPtr->rFifo.flFrame);

}

 Related Topics


PARAM_CMPTIME

What is the user asked?

The user is asked to enter a time value and to choose a comparison process.

Value entering the action/condition routine

Your condition routine doesn't have to do the comparison itself, Click & Create handles the comparison automatically. This routine shouldn't return a value of true or false, but rather a long value to be compared to the value entered by the user. Therefore, the value of the parameter you get by entering the condition routine has no purpose.

Comments

Please refer to the PARAM_COMPARAISON parameter.

 Related Topics


PARAM_CMPSTRING

What is the user asked?

The user is asked to enter a string or string expression and a comparison process.

Value entering the action/condition routine

Your condition routine doesn't have to do the comparison itself, Click & Create handles the comparison automatically. This routine shouldn't return a value of true or false, but rather a long value to be compared to the value entered by the user. Therefore, the value of the parameter you get by entering the condition routine has no purpose.

Comments

Please refer to the PARAM_COMPARAISON parameter.

 Related Topics


Action and condition parameters

Actions and conditions can ask the user up to two different parameters. These parameters can be numeric expressions, strings, or pointers to other objects or zones, etc.

You must specify that one action or one condition has a parameter in the infosEvents array of your extension. Simply specify the code of the parameter to use in the param field of the structure.

The action and condition parameters are:

•	 PARAM_TIME

•	 PARAM_BORDER

•	 PARAM_PLAYER

•	 PARAM_KEY

•	 PARAM_SPEED

•	 PARAM_POSITION

•	 PARAM_JOYDIR

•	 PARAM_ZONE

•	 PARAM_EXPRESSION

•	 PARAM_COLOUR

•	 PARAM_NEWDIRECTION

•	 PARAM_CLICK

•	 PARAM_FILENAME

•	 PARAM_EXPSTRING

 Related Topics


PARAM_TIME

What is the user asked?

The user is asked to enter a time value using the second/minutes selector.

Value entering the action/condition routine

A long value representing the time in 1/1000 of a second.

 Related Topics


PARAM_BORDER

What is the user asked?

The user is asked to open the position selector to check for borders.

Value entering the action/condition routine

A short value representing the border selected by the user, the four lower bytes being used, and defined by:

#define	BORDER_LEFT	1

#define	BORDER_RIGHT	2

#define	BORDER_TOP	4

#define	BORDER_BOTTOM	8

 Related Topics


PARAM_PLAYER

What is the user asked?

The user is asked to choose a player from 0 to 3.

Value entering the action/condition routine

A short value from 0 to 3 where 0 represents player 1 and 3 represents player 4.

 Related Topics


PARAM_KEY

What is the user asked?

The user is asked to press a key.

Value entering the action/condition routine

A short value containing the virtual key code of the chosen key.

 Related Topics


PARAM_SPEED

What is the user asked?

The user is asked to choose a speed value.

Value entering the action/condition routine

A short value containing the speed, from 0 to 100.

 Related Topics


PARAM_POSITION

What is the user asked?

The user is asked to choose a position on the frame, either absolute or relative to another object, using the position selector.

Value entering the action/condition routine

A long value with hiword containing the X frame position, and lowword containing the Y frame position.

 Related Topics


PARAM_JOYDIR

What is the user asked?

The user is asked to choose a direction and/or fire using the joystick

Value entering the action/condition routine

A short value with each byte being equal to:

DIRID_S: south

DIRID_N: north

DIRID_E: east

DIRID_W: west

FIRE1: fire button one

FIRE2: fire button two

 Related Topics


PARAM_ZONE

What is the user asked?

The user is asked to define a zone on the frame.

Value entering the action/condition routine

A pointer to a short rectangle structure (even in 32-bits) containing the zone, in frame coordinates:

typedef

{

short left;

short top;

short right;

short bottom;

} SRECT;

 Related Topics


PARAM_EXPRESSION

What is the user asked?

The user is asked to enter a new numeric expression.

Value entering the action/condition routine

A long value containing the value.

 Related Topics


PARAM_COLOUR

What is the user asked?

The user is asked to choose a color from the color palette.

Value entering the action/condition routine

A long value representing the RGB value of the chosen color.

 Related Topics


PARAM_NEWDIRECTION

What is the user asked?

The user is asked to choose a direction from the 32 possible directions.

Value entering the action/condition routine

A long value with each of the 32-bits set to reflect the choices in the direction selector. Bit0 being east, bit 8 being North, bit 16 being West, and bit 24 being South.

 Related Topics


PARAM_CLICK

What is the user asked?

The user is asked to choose between a left, middle, or right click and whether the click should be a single or double click.

Value entering the action/condition routine

The low-order byte of the parameter represents left (0), middle (1) right(2), and the PARAMCLICK_DOUBLE (0x0100) flag set for double clicks.

 Related Topics


PARAM_FILENAME

What is the user asked?

The user is asked to select a file using a file selector.

Value entering the action/condition routine

A pointer to the pathname, eventually relocated if the application was moved and if the pathname was relative to it.

Comments

If you want, define the filter to use in the file selector. To do so, you need to define your filter as a string in the resource of your extension, and insert the number of the string in the paramTitle field of the infosEvents array.

Example

Here is the definition of the "Load text" action from the EDIT object

{ACT_LOADTEXT,0,PARAM_FILENAME,0,M_TEXTTITLE,M_TEXTFILTER}, with the strings being:

M_AVITITLE,"Please select a video for Windows file"

M_AVIFILTER,"Video for Windows Files|*.avi|"

Note: The separator used in the filter string has to be a | (pipe) character, instead of a zero as Microsoft demands.

 Related Topics


PARAM_EXPSTRING

What is the user asked?

The user is asked to enter a string or a string expression.

Value entering the action/condition routine

A (far) pointer to the string, finished by zero.

 Related Topics


Expression-only parameters

The expression-only parameters are:

•	 EXPPARAM_LONG

•	 EXPPARAM_STRING

 Related Topics


EXPPARAM_LONG

What is the user asked?

The user is asked to enter a numeric expression in the expression evaluator. This expression can consist of a simple number, or a complex expression with brackets and functions.

Value entering the action/condition routine

A long value containing the result of the expression.

 Related Topics


EXPPARAM_STRING

What is the user asked?

The user is asked to enter a string expression in the expression evaluator. This expression can consist of a simple string, or a complex expression with brackets and functions.

Value entering the action/condition routine

A (far) pointer to the beginning of the string, ended by zero.

 Related Topics


How to control a window from an extension


Overview: How to control a window from an extension
How to control a window from an extension

A lot of objects need to open a window above the frame in Click & Create. For example, controls, videos, and MCI, etc. Such a window has to be a child window of the frame window. You need to be able to receive the messages from your window and intercept the messages send to the frame window, such as notification messages.

Click & Create provides you with all the tools you need to fine control your window.

Please look at the Edit object source code for information on the following functions: CreateRunObject, WindowProc, DestroyRunObject, and OEFLAGS definition in ext.h.

For more information see the following:

 Interception of frame-window notification messages

 Opening a new window

 Subclass your window

 Your main window procedure

 How to handle palette messages

 Resizing the windows depending on the zoom option

 Source example: the RTF object

 Related Topics


Interception of frame-window notification messages


Overview: Interception of frame-window notification messages
Interception of frame-window notification messages

It's very simple to intercept every Windows messages sent to the frame window. Such messages can be palette messages, notification code, etc.

Two things to do:

•	Set the OEFLAG_WINDOWPROC in the OEFLAGS field of the extension.

•	Define a function called WindowProc (see Run-time function list) to handle the messages.

You can eventually define the priority of your routine, if you want to be the first one to be called: #define WINDOWPROC_PRIORITY 100. 100 being the average priority level, 0 being very low priority and 255 the highest priority.

 Related Topics


Overview: Opening a new window
Opening a new window

Usually, windows are opened in the CreateRunObject routine, and destroyed in the DestroyRunObject routine.

Use a normal Windows routine, such as CreateWindow to open the window, and store its handle in the RUNDATA structure. We highly suggest that your window is a child window of the frame window.

Coordinate conversions

The coordinates of the object found in the headerObject substructure, at the beginning of your RUNDATA structure, contain the frame coordinates for your object. You must convert these coordinates into frame window client coordinates. This is done by simply subtracting the fields rhWindowX and rhWindowY contained in the RunHeader structure.

Example of opening a control window

// To get rhPtr & ryPtr

rhPtr = rdPtr->rHo.hoAdRunHeader;

ryPtr = (fpry)((fpchar)rhPtr + rhPtr->rhyOffset);

// Create the window

rdPtr->hWnd = CreateWindow("EDIT", NULL, dwStyle,

rdPtr->rHo.hoX - rhPtr->rhWindowX,

rdPtr->rHo.hoY - rhPtr->rhWindowY,

rdPtr->rHo.hoImgWidth,

rdPtr->rHo.hoImgHeight,

ryPtr->ryHeditWin,

NULL,

rhPtr->rh4.rh4Instance,

NULL);

dwStyle: should contain at least WS_CHILD

rdPtr->rHo.hoX - rhPtr->rhWindowX: client X coordinate of the object

rdPtr->rHo.hoY - rhPtr->rhWindowY: client Y coordinate of the object

rdPtr->rHo.hoImgWidth: width of the object

rdPtr->rHo.hoImgHeight: height of the object

ryPtr->ryHeditWin: handle of the frame window

rhPtr->rh4.rh4Instance: instance of Corel Click & Create application

You have now opened a window over the frame, but you have no control over it. The next chapter covers how to intercept the parent window notifications and the messages of the window itself.

 Related Topics


Overview: Subclass your window
Subclass your window

Subclass the window

If your window is a control object (such as a button, a list box, etc.), you want to be able to handle the notification messages relative to this window. You will have to define the OEFLAG_WINDOWPROC flag and define the WindowProc procedure. However, this isn't enough. A notification message only contains a window handle (HWND), but no pointer to the RUNDATA structure associated with the window. Click & Create provides a simple system of subclassement so that you can retrieve the RUNDATA easily.

Here is how to proceed:

In order to make the window handle available to Click & Create you must insert the following data fields in your RUNDATA structure (the two fields must follow each other)

// Structure for Click & Create

#define MAX_WINDOWS xxx

short	rWindowNumber;

HWND	hwnd[MAX_WINDOWS];

MAX_WINDOWS contains the number of windows that this object plans to open. Prior to calling the hook function, you must set a pointer to the rWindowNumber field in the headerObject sub-structure of your RUNDATA structure:

rdPtr->hwnd[0]=my_window_handle;

rdPtr->raviWindowNumber = MAX_WINDOWS;

rdPtr->rHo.hoOffsetToWindows = (short)((fpchar)&rdPtr->raviWindowNumber - (fpchar)rdPtr);

callRun-timeFunction(rdPtr, RFUNCTION_SUBCLASSWINDOW, 0, 0);

Here is an example of a WindowProc routine that recovers the address of the RUNDATA structure, in both 16- and 32-bits:

LRESULT CALLBACK DLLExport WindowProc(fprh rhPtr, HWND hWnd, UINT msgType, WPARAM wParam, LPARAM lParam)

{

fprdata	rdPtr;

// If pause, out

if (rhPtr->rh2.rh2PauseCompteur != 0)

return 0;

// It's for me ?

switch (msgType)

{

// Handle the messages I want to intercept...

case WM_COMMAND:

switch (wmCommandNotif)

{

case BN_CLICKED:

// It's for me ???

#ifndef WIN32

if ((rdPtr = GetRdPtr(LOWORD(lParam), rhPtr, &n)) != NULL && (IDENTIFIER == rdPtr->rHo.hoIdentifier))

#else

if ((rdPtr = GetRdPtr((HWND)lParam, rhPtr, &n)) != NULL && (IDENTIFIER == rdPtr->rHo.hoIdentifier))

#endif

{

// ... do whatever I want here...

// Intercept the message

return REFLAG_MSGHANDLED;

}

break;

default:

break;

}

return 0;

// Sniff, Not for me ...

default:

return 0;

}

}

The first thing to do is to check that you are not in pause mode. If you are in pause mode, the extension object should not react to user inputs.

Then, you must get the address of the RUNDATA structure corresponding to this window when the window was subclassed. Click & Create inserted data in the window structure. The GetRdPtr routine retrieves the address of the RUNDATA structure from the hook:

fprdata GetRdPtr(HWND hwnd, fprh rhPtr)

{

#ifdef WIN32

return (fprdata)GetProp(hwnd, (LPCSTR)rhPtr->rh4.rh4AtomRd);

#else

return (fprdata)MAKELONG(GetProp(hwnd, (LPCSTR)rhPtr->rh4.rh4AtomLRd), GetProp(hwnd, (LPCSTR)rhPtr->rh4.rh4AtomHRd));

#endif

}

However, retrieving the address is not enough, you may have more than one object with a window on the frame at a tune. This is why it's very important to check the object identifier, and make sure that it match the object identifier.

IDENTIFIER == rdPtr->rHo.hoIdentifier

 Related Topics


Overview: Your main window procedure
Your main window procedure

For windows other than control windows, you will need to define a real window procedure. You'll have to define a hook on your window to link it to the Click & Create window processing.

Here is how we proceed with the window procedure in the QTVR object:

First, we register the window class in the Initialize routine:

// Register the QTVR window class

wcMov.style = 0;

wcMov.lpfnWndProc = (WNDPROC)WndProc;

wcMov.cbClsExtra = 0;

wcMov.cbWndExtra = 0;

wcMov.hInstance = hInstLib;

wcMov.hIcon = NULL;

wcMov.hCursor = LoadCursor(NULL, IDC_ARROW);

wcMov.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wcMov.lpszMenuName = NULL;

wcMov.lpszClassName = szMovClass;

if (RegisterClass(&wcMov) != 0)

QuickTimeInit++;

In the CreateRunObject routine, we create the window of this class:

rdPtr->hwndMov = CreateWindow(szMovClass,

NULL,

WS_CHILDWINDOW,

rdPtr->rHo.hoX - rhPtr->rhWindowX,

rdPtr->rHo.hoY - rhPtr->rhWindowY,

rdPtr->rHo.hoImgWidth,

rdPtr->rHo.hoImgHeight,

ryPtr->ryHeditWin,

NULL,

hInstLib,

NULL);

Now we set the hook:

// Branch the hook

rdPtr->raviWindowNumber = 1;

rdPtr->rHo.hoOffsetToWindows = (short)((fpchar)&rdPtr->raviWindowNumber - (fpchar)rdPtr);

callRun-timeFunction(rdPtr, RFUNCTION_SUBCLASSWINDOW, 0, (DWORD)WndHookProc);

Notice that the we transmit the address of the hook routine as the last parameter of the callRun-timeFunction routine.

Now the true window routine, that does nothing:

LRESULT CALLBACK DLLExport WndProc(HWND hWnd, uint msgType, WPARAM wParam, LPARAM lParam)

{

return DefWindowProc(hWnd, msgType, wParam, lParam);

}

The hook procedure that does the job:

LRESULT CALLBACK DLLExport WndHookProc(fprh rhPtr, HWND hWnd, uint msgType, WPARAM wParam, LPARAM lParam)

{

fprdata	rdPtr;

short	p;

// Process messages

rdPtr=GetRdPtr(hWnd, rhPtr);

if (rdPtr!=0)

{

// Do my stuff here...

...

// Send message to movie controller or returns

return MCIsPlayerMessage(rdPtr->mcController, hWnd, msgType, wParam, lParam);

}

return 0;

}

The hook procedure is called before the true procedure. It should return a value different from 0 to indicate that the message has been handled. In this case the WndProc routine is not called.

 Related Topics


Overview: How to handle palette messages
How to handle palette messages

When an application runs in 256 colors, a child-window must properly respond to palette messages. Here is how to do it:

LRESULT CALLBACK DLLExport WindowProc(fprh rhPtr, HWND hWnd, UINT msgType, WPARAM wParam, LPARAM lParam)

{

fpry	ryPtr;

fprdata	rdPtr;

HWND	hwndT;

HWND	hwndNewPal;

// It's for me ?

switch (msgType)

{

// Palette messages

case WM_PALETTECHANGED:

case WM_QUERYNEWPALETTE:

// Look for AVI windows with their own palette

ryPtr = (fpry)((LPBYTE)rhPtr + rhPtr->rhyOffset);

if ( NULL == ryPtr->ryHeditWin || ryPtr->ryHmainWin != hWnd)

break;

rdPtr = NULL;

hwndNewPal = NULL;

hwndT = GetWindow(ryPtr->ryHeditWin, GW_CHILD);

while (hwndT)

{

// Get pointer on avi struct

rdPtr = GetRdPtr(hwndT, rhPtr);

if ((rdPtr != 0) && (IDENTIFIER == rdPtr->rHo.hoIdentifier))

{

if (msgType == WM_PALETTECHANGED)

SendMessage (hwndT, WM_PALETTECHANGED, wParam, lParam);

else

{

// Sen a WM_QUERYNEWPALETTE to the AVI and a WM_PALETTECHANGED to frame window

if (NULL == hwndNewPal)

SendMessage(hwndNewPal = hwndT, WM_QUERYNEWPALETTE, 0, 0);

else

SendMessage(hwndT, WM_PALETTECHANGED, (WPARAM)hwndNewPal, 0);

}

}

break;

}

hwndT = GetWindow(hwndT, GW_HWNDNEXT);

}

if ( hwndNewPal != NULL )

{

SendMessage(ryPtr->ryHeditWin, WM_PALETTECHANGED, (WPARAM)hwndNewPal, 0);

// Indicates that the message has been treated

return REFLAG_MSGHANDLED;

}

break;

}

return 0L;

}

As you can see, this routine detects the palette messages. When a palette message occurs, it goes through the list of child AVI windows. When one is detected, it sends a QUERYNEWPALETTE message to the window, and a PALETTECHANGED message to the frame window.

Even though such an object is not actually drawn in the frame, you should only modify the position and size of the window in the DisplayRunObject routine. Doing this ensures that all the modifications done by the actions have an effect all at one, synchronized with the main redraw process of the application.

 Related Topics


Overview: Resizing the windows depending on the zoom option
Resizing the windows depending on the zoom option

One exciting feature of Click & Create is that you can zoom the application display in run-time. For example, you can have a 640 x 480 window zoomed into 1024 x 768. Your application, if it uses windows, should resize the window if the application is zoomed, so that the proportions are respected.

The following routine converts a rectangle structure from frame coordinates into window coordinates respecting the zoom option.

void PlayfieldCoordToWindow(fprdata rdPtr, RECT _far * rcDest)

{

fprh	rhPtr;

fpry	ryPtr;

long	cx, cy;

RECT	rc1, rc2;

rhPtr=rdPtr->rHo.hoAdRunHeader;

ryPtr=(fpry)((fpchar)rhPtr+rhPtr->rhyOffset);

// Frame coordinates -> client coordinates

rcDest->left-=(int)rhPtr->rhWindowX;

rcDest->right-=(int)rhPtr->rhWindowX;

rcDest->top-=(int)rhPtr->rhWindowY;

rcDest->bottom-=(int)rhPtr->rhWindowY;

// Zoom mode?

if ((rhPtr->rhGameFlags&GAMEFLAGS_REALGAME)==0 || (ryPtr->ryGame.gaFlags&GA_STRETCH)==0)

return;

// Perform the conversion

GetClientRect(ryPtr->ryHeditWin, &rc1);

if (rc1.right==0 || rc1.bottom==0) return;

WinGetLogRect(rhPtr->rhIdEditWin, &rc2);

cx=((long)rc1.right<<16)/((long)rc2.right);

cy=((long)rc1.bottom<<16)/((long)rc2.bottom);

rcDest->left=(int)((((long)rcDest->left)*cx)>>16);

rcDest->top=(int)((((long)rcDest->top)*cy)>>16);

rcDest->right=(int)((((long)rcDest->right)*cx)>>16);

rcDest->bottom=(int)((((long)rcDest->bottom)*cy)>>16);

}

 Related Topics


Overview: Source example: the RTF object
Source example: the RTF object

The RTF object is a very complex extension object. The RTF object can draw itself in the frame and open horizontal and vertical scroll bars at the same time.

•	OEFLAG_SPRITE|OEFLAG_QUICKDISPLAY: draws the RTF object in the frame

•	OEFLAG_WINDOWPROC: opens horizontal and vertical scroll bars

Because the RTF object is so difficult, you will find the source code of the window control routines in the extension kit: WINDOWS.C

 Related Topics


Important structures


Overview: Important structures
Important structures

In this chapter, most of the important structures that you must know and use in order to program your extension object are listed. Some of these structures are part of the extension sourcecode, some are part of Corel Click & Create sources (defined in cnpf.H and cnpy.h), and some are part of the graphic dll CNCS.DLL.

The important structures are:

•	 EDITDATA

•	 mv

•	 ObjInfo

•	 LevelObject

•	 RUNDATA

•	 HeaderObject

•	 RunHeader

•	 Rhy

 Related Topics


EDITDATA

Defined in

EXT.H, part of the extension code.

Purpose

Stores the edition-time settings of the object, defined in the setup dialog box for that object. This structure is actually defined by you!

EDITDATA must begin with a sub-structure extheader that contains information for Click & Create.

Comments

Here is the minimum EDITDATA structure:

typedef struct

{

extHeader eHeader;

} EDITDATA;

Here is the extheader structure:

typedef struct tagEditExtension

{

short extSize;	// Size of the structure

short extMaxSize;	// Maximum edition size

short extOldFlags;	// Free (but don't touch it!)

short extVersion;	// Version number

} extHeader;

Note: You should not change this structure.

 Related Topics


mv

Defined in

CNPY.H part of Click & Create main source.

Purpose

Contains the information structure about the Click & Create application to help the extension objects perform their tasks.

Layout

typedef	struct {

HINSTANCE	mvHInst;

npAppli	mvIdAppli;

npWin	mvIdMainWin;

npWin	mvIdEditWin;

HWND	mvHMainWin;

HWND	mvHEditWin;

HPALETTE	mvHPal256;

Game	mvGameHeader;

Level	mvLevelHeader;

WORD	mvAppMode;

WORD	mvScrMode;

WORD	mvMode65000;

LPSTR	mvKncTitle;

BOOL ( CALLBACK * mvKncHelp) (LPSTR, UINT, DWORD);

int ( CALLBACK * mvKncAddEditSpr) (fpLevObj, npSpr);

short( CALLBACK * mvEditImage) (HWND, WORD, WORD, LPSTR, int, int, int);

short( CALLBACK * mvEditFont) (HWND, WORD, COLORREF FAR *, DWORD);

LPBYTE ( CALLBACK * mvGetOcAddress) (HFRAN);

COLORREF ( CALLBACK *mvChooseColour) (HWND, COLORREF, int);

int	 ( CALLBACK * mvGetProfileInt) (LPSTR, LPSTR, int);

int	 ( CALLBACK * mvGetProfileString) (LPSTR, LPSTR, LPSTR, LPSTR, int);

int	 ( CALLBACK * mvWriteProfileInt) (LPSTR, LPSTR, int);

int	 ( CALLBACK * mvWriteProfileString) (LPSTR, LPSTR, LPSTR);

} mv;

Useful fields

HINSTANCE mvHInst instance handle of Click & Create application

npAppli mvIdAppli CNCS application handle of Click & Create (see CNCS documentation)

npWin mvIdMainWin CNCS handle of main application window (the main MDI window)

npWin mvIdEditWin CNCS handle of the frame window

HWND mvHMainWin handle of main window

HWND mvHEditWin handle of frame window

HPALETTE mvHPal256 handle of the current color palette in 256 colors

WORD	mvAppMode current graphic mode and flags

WORD	mvScrMode current graphic mode

SM_8 = 256 colors

SM_16 = 32768 / 65536 colors

SM_24 = 16 million colors

WORD	mvMode65000 if mv SCR Mode == SM_16:

0 = 32768 colors

! = 0 = 65536 colors

LPSTR	mvKncTitle far pointer to the name of the application (Corel Click & Create)

BOOL ( CALLBACK * mvKncHelp) (LPSTR, UINT, DWORD) call the help utility (see template)

short( CALLBACK * mvEditImage) (HWND, WORD, WORD, LPSTR, int, int, int); create and edit a CNCS image

short( CALLBACK * mvEditFont) (HWND, WORD, COLORREF FAR *, DWORD); create and edit a CNCN font

COLORREF ( CALLBACK *mvChooseColour) (HWND, COLORREF, int) opens Click & Create color selector and returns the chosen color

int ( CALLBACK * mvGetProfileInt) (LPSTR, LPSTR, int) returns a integer from Click & Create private INI file

int ( CALLBACK * mvGetProfileString) (LPSTR, LPSTR, LPSTR, LPSTR, int) returns a string from Click & Create private INI file

int ( CALLBACK * mvWriteProfileInt) (LPSTR, LPSTR, int) write an integer in Click & Create private INI file

int ( CALLBACK * mvWriteProfileString) (LPSTR, LPSTR, LPSTR) write a string in Click & Create private INI file

 Related Topics


ObjInfo

Defined in

CNPY.H part of Click & Create main sources.

Purpose

Stores information about one object on a frame. Only one ObjInfo structure is defined for duplicated objects on the frame.

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

typedef	struct tagObIn

{

char	oiName[OINAME_SIZE];

union	{

BYTE	oiFree[14];

struct	{

COLORREF	oiSprColor;

WORD	oiSprFree[5];

} oiSpr;

} oiSys;

WORD	oiPrefs;

short	oiGlobal;

WORD	oiFlags;

WORD	oiLoadCount;

WORD	oiButtImg;

WORD	oiCount;

HFRAN	oiHFran;

WORD	oiImg;

WORD	oiWSave;

WORD	oiDelCount;

DWORD 	oiEffectParam;

DWORD	oiFileOff;

} ObjInfo;

Useful fields

char oiName[OINAME_SIZE]	Object name

Word	oiPrefs	Object preferences: may be one or more of the following values:

OIP_DONTSAVEBKD	Do not save background

OIP_SOLIDBKD	Erase background with solid color

OIP_INKEFFECTMASK	Ink effect (mask in oilPrefs)

OIP_INKEFFECTSHIFT	Ink effect (shift)

Ink effect = (oilPrefs & mask) >> shift

These preferences are setup in the Object Preferences dialog box. You can only use them if you display your object manually.

DWORD: oiEffectParam	Parameter of ink effect (See PasteSpriteEffect).

 Related Topics


LevelObject

Defined in

CNPY.H, part of Click & Create main sources.

Purpose

Stores information about each individual object in a frame. One "LevelObject" per object, even if the object has been duplicated. Duplicated objects will have the same ObjInfo structure.

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

typedef	struct tagLeOb

{

short	loOiNum;

short	loX;

short	loY;

WORD	loFlags;

WORD	loImg;

WORD	loFlags2;

HFRAN	loHFran;

union	{

struct	{

WORD	loAnim;

WORD	loFrame;

WORD	loTempo;

WORD	loPlane;

WORD	loDir;

short	loFree1;	// libre

short	loFree2;	// libre

}loa;

struct	{

COLORREF	loBoxColor1;

COLORREF	loBoxColor2;

WORD	loBoxFlags;

short	loBoxCx;

short	loBoxCy;

}lob;

}lou;

short	loParent;

} levObj;

Useful fields

short loX;	Playfield X coordinate of the object

short loY;	Playfield Y coordinate of the object

 Related Topics


RUNDATA

Defined in

EXT.H, part of the extension code.

Purpose

Stores information about the object during run-time. The RUNDATA structure must always begin with a headerObject, followed by movement, animation, common, and value structures, depending on the OEFLAG flags. Refer to Defining the object properties chapter.

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

Here is the simplest RUNDATA structure:

typedef struct

{

headerObject rHo;

} RUNDATA;

Useful fields

See headerObject structure.

 Related Topics


HeaderObject

Defined in

CNPF.H, part of Click & Create main sources.

Purpose

Stores object-independent run-time information. The HeaderObject structure should always be at the beginning of a RUNDATA structure.

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

typedef struct tagHO {

short 	hoNumber;

short 	hoNextSelected;

short	hoSize;

fprh	hoAdRunHeader;

ulong	hoAddress;

short 	hoHlo;

short 	hoOi;

short 	hoOiPrev;

short 	hoOiNext;

short 	hoType;

short 	hoCreationId;

ulong 	hoOiList;

ulong 	hoEvents;

ulong	hoOffset;

ulong	hoPrevNoRepeat;

ulong	hoBaseNoRepeat;

short 	hoMark1;

short 	hoMark2;

short	hoFree1;

short	hoFree2;

ushort	hoCommonSeg;

ulong	hoCommon;

short 	hoCalculX;

short 	hoX;

short 	hoCalculY;

short 	hoY;

short	hoImgXSpot;

short	hoImgYSpot;

short	hoImgWidth;

short	hoImgHeight;

RECT	hoRect;

short	hoOEFlags;

int	hoOffsetValue;

short	hoFlags;

WORD	hoPlane;

long	hoHandleRoutine;

long	hoModifRoutine;

long	hoDisplayRoutine;

short	hoNextQuickDisplay;

HGLOBAL hoHgBack;

ulong	hoAdBack;

RECT	hoRectSave;

short	hoLimitFlags;

long	hoFree3;

short	hoOffsetToWindows;

long	hoIdentifier;

} headerObject;

Useful fields

short	hoNumber number of the object in internal Click & Create object list (RO)

short	hoSize size of the RUNDATA structure (RO)

fprh	hoAdRunHeader address (far) of the runHeader structure (RO)

ushort	hoCommonSeg 16-bits only, segment of the ObjectCommon structure (RO)

ulong	hoCommon 16-bits: offset of ObjectCommon structure, 32-bits, pointer to the same structure (RO)

short	hoX frame coordinate of the object (RW)

short	hoY frame coordinate of the object (RW)

short	hoImgXSpot X position of hot spot in the object (RW)

short	hoImgYSpot Y position of hot spot in the object (RW)

short	hoImgWidth width of the object (RW)

short	hoImgHeight height of the object (RW)

short	hoOEFlags copy of OEFLAGS definition

 Related Topics


RunHeader

Defined in

CNPF.H, part of Click & Create main sources.

Purpose

Stores application information during run-time. Usually, you need to access this structure to get the handle of the window.

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

This structure is too big to be listed here.

Useful fields

npWin rhIdEditWin CNCS handle of frame window

npWin rhIdMainWin CNCS handle of main window

npAppli	rhIdAppli CNCS handle of application

int rhyOffset offset to RHY structure from RunHeader structure. In RHY you will find other useful fields as handles of windows and palettes.

 Related Topics


Rhy

Defined in

CNPY.H, part of Click & Create main sources.

Purpose

Stores application information during run-time. You can get the address of this structure by adding its offset to the address of the RunHeader structure. Here is how you usually proceed:

LPRUNDATA	rdPtr;

RunHeader _far * 	rhPtr;

rhy _far *	ryPtr;

rhPtr=rdPtr->rHo.hoAdRunHeader;

ryPtr=(rhy _far *)((LPBYTE)rhPtr+rhPtr->rhyOffset);

Warning: Only access the "useful fields", changes to any other areas may completely destroy an application!

Layout

typedef	struct	tagRhy {

HWND	ryHmainWin;

HWND	ryHeditWin;

HGLOBAL	ryHgLadder;

fpshort	ryAdLadder;

Game	ryGame;

Level	ryLevel;

short	ryMusics[MAX_MUSIC_PER_LEVEL];

WORD	ryScrMode;

WORD	ryCurrentMus;

HGLOBAL	ryHgMusReloc;

LPWORD	ryTabMusReloc;

HGLOBAL	ryHgSndReloc;

LPWORD	ryTabSndReloc;

char	ryGameName[260];

DWORD	ryFree1;

DWORD	ryFree2;

short	ryEvent;

short	ryEventParam;

short	ryFlags;

short	ryFree3;

DWORD	ryFree4;

HGLOBAL	ryHgPasswords;

LPSTR	ryAdPasswords;

DWORD	ryLives[4];

DWORD	ryScore[4];

DWORD	ryGlobal[16];

fontCache	ryCacheFnt[MAX_FONTCACHE];

} rhy;

Useful fields

HWND	ryHmainWin handle of main window

HWND	 ryHeditWin handle of frame window

Game	ryGame	Information on the application; usual fields:

char gaTitle[];	Application title

char gaAuthor[];	Application author

short gaCxWin;	Default width of the main window

short gaCyWin;	Default height of the main window

DWORD gaBorderColour;	Background color of the main window

WORD gaFlags;	Flags; usual flags:

GA_SPEEDINDEPENDANT	Machine-independent speed

GA_STRETCH	Resize display to fill current window size

WORD gaCtrlType[]; Control type per player (0=mouse,1=joy1, 2=joy2, 3=keyb)

WORD gaCtrlKeys[4][6]; Control keys per player

Level	ryLevel	Information on the current frame; usual fields:

short leX;	Current X coordinate. of the top-left corner (frame window)

short leY;	Current Y coordinate. of the top-left corner

short leWidth;	Playfield width in pixels

short leHeight;	Playfield height in pixels

char	leTitle[];	Frame Title

WORD	leu.leLev.leNbPlayers; 	Number of players

COLORREF	leu.leLev.leBackground;	Playfield background color

WORD ryScrMode	 same as mvScrMode, current graphic mode

SM_8 = 256 colors

SM_16 = 32768 / 65536 colors

SM_24 = 16 million colors

char ryGameName[260] pathname of the current application

DWORD ryLives[4] lives of all four players

DWORD ryScore[4] scores of all four players

DWORD ryGlobal[16] content of all 16 global values

 Related Topics


Click & Create routines accessible from within an extension


Overview: Click & Create routines accessible from within an extension
Click & Create routines accessible from within an extension

We have made public a few routines from Click & Create to simplify the task of creating an extension object. Be sure to look at:

•	 Routines accessible in edition time

•	 Routines accessible in run time

 Related Topics


Routines accessible in edition time

Edition-time routines can be accessed though the mv structure and transmitted to every edition function in Click & Create.

The routine provided in edition time are:

•	 mvKncHelp

•	 mvEditImage

•	 mvEditFont

•	 mvGetOcAddress

•	 mvChooseColor

•	 mvGetProfileInt

•	 mvGetProfileString

•	 mvWriteProfileInt

•	 mvWriteProfileString

 Related Topics


mvKncHelp

BOOL ( CALLBACK * mvKncHelp) (LPSTR modName, UINT contextId, DWORD helpId);

This function calls the help window.

Parameters

LPSTR modName: name of the extension

UINT contextId: help context identifier

DWORD helpId: help page identifier

Return value

TRUE if the help file could opened, FALSE if an error occurred.

Comments

Please refer to the chapter on Creating your own help file for more information on the help system.

Example

This is how we call the help from the setup dialog box of every object:

NPSTR	chTmp;

if ((chTmp = (NPSTR)LocalAlloc(LPTR, _MAX_PATH)) != NULL)

{

GetModuleFileName(hInstLib, chTmp, _MAX_PATH);

mvPtr->mvKncHelp(chTmp, HELP_CONTEXT, 1);

LocalFree((HLOCAL)chTmp);

}

 Related Topics


mvEditImage

short( CALLBACK * mvEditImage) (HWND hWin, WORD oldImg, WORD reserved, LPSTR winTitle, int flags, int defWidth, int def Height)

This function allows you to create and edit an image using the Picture Editor, for use with the CNCS image functions (PasteSprite, ImageToDib, etc.)

Parameters

hWin	Parent window

oldImg	Image to edit. 0= create a new image

reserved	Must be 0.

winTitle	Sting to display in the caption bar of the Picture Editor.

flags	may be one or more of the following values:

EPF_HOTSPIOT	Allows you to edit the Hotspot

EPF_FIXEDSIZE	Fixed size

defWidth	Default image width

defHeight	Default image height

Return value

0 if there is an error OR if the user clicked CANCEL

>1 = 1 = image number

Comments

After using the image, it must be deleted using the DelImage function. If the image is to be saved in the application image bank, it should be enumerated in the EnumElt function.

 Related Topics


mvEditFont

short( CALLBACK * mvEditFont) (HWND hWin, WORD oldFont, COLORREF FAR *color, DWORD flags);

This function allows you to create and edit a CNCS font, for use with the CNCS font functions (WinCreateFont, etc.). Because CNCS fonts are identical to Windows fonts, you can ignore this function for this version of Click & Create.

Parameters

hWin	Parent Window

oldFont	Old font

color	Font color

flags	Flags used in the Window ChooseFont function

Return value

0 if there is an error OR if the user clicked CANCEL

> = 1 = font number

Comments

After using the font, it must be deleted using the DelFont function. If the font is to be saved in the application font bank, it should be enumerated in the EnemElt function.

 Related Topics


mvGetOcAddress

LPBYTE ( CALLBACK * mvGetOcAddress) (HFRAN hf);

This routine returns the address of the ObjectCommon structure of an object from its identifier, called a HFRAN.

Parameters

HFRAN hf: the memory identifier of the object.

Return value

If successful, the address of the structure, if not, zero.

Comments

The ObjectCommon structure is an internal structure used by Click & Create. You will find it in CNPF.H. We did not add comments to this file on purpose. This routine contains the movement, animation, value edition structure, and also the EDITDATA structure for your Click & Create extension object.

Warning: You should not make changes to this routine!

 Related Topics


mvChooseColor

COLORREF ( CALLBACK *mvChooseColour) (HWND hWindow, COLORREF rgb, int colourMode);

This routine opens the Click & Create color selector and asks the user to choose a color.

Parameters

HWND hWindow: handle of the parent window

COLORREF rgb: current color

int colourMode: current color mode

Return value

The RGB value of the color chosen by the user, -1L if the user chooses CANCEL.

Comments

The colourMode value can have the following values: SM_8 for a 256 colors selector, SM_4 for a 16 colors selector.

Example

In the RTF object setup dialog, you can choose the color of the background. Here is how we proceed, and then fill the sample area with the color:

if ( (newCol=mvPtr->mvChooseColour(hDlg, edPtr->backColor, SM_8))!=-1L )

{

edPtr->backColor=newCol;

wDC=GetDC(hDlg);

FillBoxColor (spa->kv, hDlg, wDC, IDC_COLOR, edPtr->backColor|0x2000000L);

ReleaseDC(hDlg, wDC);

}

 Related Topics


mvGetProfileInt

int ( CALLBACK * mvGetProfileInt) (LPSTR section, LPSTR key, int defaultValue);

This routine returns a value from Click & Create profile file (INI).

Parameters

LPSTR section: pointer to a section identifier.

LPSTR key: pointer to a key identifier.

int defaultValue: default value if not found.

Return value

If the function succeeds, the return value is the integer equivalent of the string following the key name in WIN.INI. If the function cannot find the key, the return value is the default value. If the value of the key is less than zero, the return value is zero.

Comments

Please refer to Microsoft documentation about the profile files.

This function allows your extension to have its own entries in the Click & Create main INI file, and thus avoiding messing up the system by creating multiple INI files for each extension object.

Note: Please create your own section, with a name that cannot conflict with the other names, and restrict the amount of data to the minimum (in 16-bits, INI files are limited to 64K).

 Related Topics


mvGetProfileString

int ( CALLBACK * mvGetProfileString) (LPSTR section, LPSTR key, LPSTR defString, LPSTR string, int cbString);

This routine returns a string from the Click & Create profile file (INI).

Parameters

LPSTR section: pointer to a section identifier.

LPSTR key: pointer to a key identifier.

LPSTR defString: pointer to the string to create if the entry does not exist.

LPSTR string: points to the buffer that receives the retrieved string.

int cbString: specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.

Return value

If the function succeeds, the return value is the number of characters copied to the buffer, not including the null-terminating character.

If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one.

If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.

Comments

Please refer to Microsoft documentation about the profile files.

This function allows your extension object to have its own entry in the Click & Create main INI file, thus avoiding messing up the system by creating multiple INI files for each extension.

Note: Please create your own section, with a name that cannot conflict with the other names, and restrict the amount of data to the minimum (in 16-bits, INI files are limited to 64K).

 Related Topics


mvWriteProfileInt

int ( CALLBACK * mvWriteProfileInt) (LPSTR section, LPSTR key, int value);

This routine writes a integer value in the Click & Create profile file (INI).

Parameters

LPSTR section: pointer to a section identifier.

LPSTR key: pointer to a key identifier.

int value: contains the value to be written.

Return value

Nonzero if successful; otherwise 0

Comments

Please refer to Microsoft documentation about the profile files.

This function allows your extension object to have its own entry in the Click & Create main INI file, thus avoiding messing up the system by creating multiple INI files for each extension.

Note: Please create your own section, with a name that cannot conflict with the other names, and restrict the amount of data to the minimum (in 16-bits, INI files are limited to 64K).

 Related Topics


mvWriteProfileString

int ( CALLBACK * mvWriteProfileString) (LPSTR section, LPSTR key, LPSTR string);

This routine writes a string in Click & Create profile file (INI).

Parameters

LPSTR section: pointer to a section identifier.

LPSTR key: pointer to a key identifier.

LPSTR string: pointer to the null-terminated string to be written.

Return value

If the function successfully copies the string to the WIN.INI file, the return value is TRUE.

If the function fails, or if it flushes the cached version of WIN.INI, the return value is FALSE. To get extended error information, call GetLastError.

Comments

Please refer to Microsoft documentation about the profile files.

This function allows your extension object to have its own entry in the Click & Create main INI file, thus avoiding messing up the system by creating multiple INI files for each extension.

Note: Please create your own section, with a name that cannot conflict with the other names, and restrict the amount of data to the minimum (in 16-bits, INI files are limited to 64K).

 Related Topics


Routines accessible in run-time

Your object must have access to a number of functions during run-time. All the calls are made through a macro defined in CNPF.H, callRun-timeFunction. The accessible run-time routines are:

•	 callRun-timeFunction

•	 RFUNCTION_REHANDLE

•	 RFUNCTION_GENERATEEVENT

•	 RFUNCTION_PUSHEVENT

•	 RFUNCTION_PUSHEVENTSTOP

•	 RFUNCTION_GETPARAM1

•	 RFUNCTION_GETPARAM2

•	 RFUNCTION_PAUSE

•	 RFUNCTION_CONTINUE

•	 RFUNCTION_REDISPLAY

•	 RFUNCTION_GETFILEINFOS

•	 RFUNCTION_SUBCLASSWINDOW

•	 RFUNCTION_REDRAW

•	 RFUNCTION_DESTROY

•	 RFUNCTION_GETSTRINGSPACE

 Related Topics


callRun-timeFunction

long callRun-timeFunction(LPRUNDATA rdPtr, short funcNum, short wParam, long lParam)

Macro defined in CNPF.H to make calling Click & Create routines during run-time simple.

Parameters

LPRUNDATA rdPtr: pointer to the object's RUNDATA routine

short funcNum: number of the function to call

short wParam: short parameter eventually needed by the function

long lParam: long parameter eventually needed by the function

Return value

Depends on the function called.

Example

How to force a redraw of your object:

callRun-timeFunction(rdPtr, RFUNCTION_REDRAW, 0, 0);

 Related Topics


RFUNCTION_REHANDLE

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_REHANDLE, short wParam, short lParam);

Forces the HandleRunObject routine to be called at next loop.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

If your HandleRunObject routine returns a value of REFLAG_ONESHOT, then it's disconnected from the list of routines to call at each loop. This function replugs the call in the list.

By carefully using this feature, you can reduce the influence of your object on the execution speed of one application. Imagine that your HandleRunObject only needs to work when something is modified in the object run-time structure, here is what you do:

•	The first HandleRunObject is called automatically after the object is created, does its job, and returns REFLAG_ONSHOT and eventually REFLAG_REDRAW if needed.

•	Whenever an action of your object modifies the run-time structure, it calls the RFUNCTION_REHANDLE so that the handle routine can start again and disconnect itself again.

We use this technique for many objects, such as the text object.

 Related Topics


RFUNCTION_GENERATEEVENT

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_GENERATEEVENT, short wParam, short lParam);

Generates an extension true event.

Parameters

short wParam: event code.

short lParam: eventual parameter, that your condition may require.

Return value

None.

Comment

In Click & Create there is a big distinction between TRUE conditions and evaluated conditions. Please refer to the section on conditions and actions for more information.

The RFUNCTION_GENERATEEVENT sends an events in the event-processing queue. The event code must be the code of one condition defined within your extension. You must also define the handling routine of this condition.

If the user has inserted a condition as the first line of one event, then your routine will be called. This event will not stop the Step-through editor.

Example

Here is how the AVI object detects when the user clicks within the AVI. This example is taken from the AVI window procedure:

case WM_LBUTTONDOWN:

p = 0;

goto WndProc_suite;

case WM_MBUTTONDOWN:

p = 1;

goto WndProc_suite;

case WM_RBUTTONDOWN:

p = 2;

goto WndProc_suite;

case WM_LBUTTONDBLCLK:

p = 0 + PARAMCLICK_DOUBLE;

goto WndProc_suite;

case WM_MBUTTONDBLCLK:

p = 1 + PARAMCLICK_DOUBLE;

goto WndProc_suite;

case WM_RBUTTONDBLCLK:

p = 2 + PARAMCLICK_DOUBLE;

WndProc_suite:

rdPtr=GetRdPtr(hDlg, rhPtr);

if (0 == rhPtr->rh2.rh2PauseCompteur && rdPtr!=0)

{

// Store position in time for condition routine

rdPtr->raviClick = p;

rdPtr->raviClickCount = rhPtr->rh4.rh4EventCount;

// Generate the event

callRun-timeFunction(rdPtr, RFUNCTION_GENERATEEVENT, CND_CLICK, 0);

}

break;

 Related Topics


RFUNCTION_PUSHEVENT

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_, short wParam, short lParam);

Pushes an extension true event that does not stop the Step-through editor.

Parameters

short wParam: event code.

short lParam: eventual parameter, that your condition may require.

Return value

None.

Comment

This function works as the RFUNCTION_GENERATEEVENT, but the event will only be called at the end of the current loop, thus allowing you to perform tasks between the moment when the event is generated and the time when the condition routine is called.

 Related Topics


RFUNCTION_PUSHEVENTSTOP

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_, short wParam, short lParam);

Pushes an extension true event that stops the step-through editor.

Parameters

short wParam: event code.

short lParam: eventual parameter, that your condition may require.

Return value

None.

Comment

This function is the same as RFUNCTION_PUSHEVENT, the only difference is that the generated event will stop the step-through editor if the user has not inserted the condition handling this event in its program.

Example

Taken from the clock object every new hour:

if (rdPtr->sNewHour != Run-time.hour)

{

rdPtr->sEventCount = (short)rhPtr->rh4.rh4EventCount;

rdPtr->sNewHour = Run-time.hour;

callRun-timeFunction(rdPtr, RFUNCTION_PUSHEVENTSTOP, CND_NEWHOUR, 0);

}

 Related Topics


RFUNCTION_GETPARAM1

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_GETPARAM1, short wParam, short lParam);

This routine is only for expression routines. It returns the value of the first parameter and sets the pointer to the beginning of the next one.

Parameters

short wParam: not used.

short lParam: long value received on entry of the expression routine, containing a pointer to the next expression.

Return value

The long value (or pointer to string) as the result of evaluating the parameter.

Comment

Only to be used if your expression needs parameters! Please refer to the chapter about Conditions, actions and expressions.

 Related Topics


RFUNCTION_GETPARAM2

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_GETPARAM2, short wParam, short lParam);

This routine is only for expression routines. It returns the value of the second parameter.

Parameters

short wParam: not used.

short lParam: long value received on entry of the expression routine, containing a pointer to the next expression.

Return value

The long value (or pointer to string) as the result of evaluating the parameter.

Comment

Only to be used if your expression needs two parameters! Should be called after you called the RFUNCTION_GETPARAM1.

Please refer to the chapter about Conditions, actions and expressions.

 Related Topics


RFUNCTION_PAUSE

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_PAUSE, short wParam, short lParam);

Enter the pause mode.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

Your extension might open a file selector or stop the execution of the application to display another dialog. We insist that you should pause the application before doing so. If you don't, then all internal timers and synchronization process will be corrupted.

 Related Topics


RFUNCTION_CONTINUE

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_CONTINUE, short wParam, short lParam);

End the pause mode.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

To be used when you finish a lengthy task.

 Related Topics


RFUNCTION_REDISPLAY

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_, short wParam, short lParam);

Force a complete redisplay of the frame.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

Warning: A complete redraw of the frame takes a lot of time. Use this function with caution. You should use it only if your object is a backdrop object (such as the picture object).

 Related Topics


RFUNCTION_GETFILEINFOS

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_GETFILEINFOS, short wParam, short lParam);

Returns information about the current application drive, pathname, name etc.

Parameters

short wParam: code of the information wanted.

short lParam: pointer to a destination buffer, should be a least _MAX_PATH long.

Return value

None, (but in the buffer).

Comment

With this routine, your object can know the complete pathname of the current application, and access files in sub-directories.

wParam can take the following values:

•	FILEINFO_DRIVE: returns the application drive

•	FILEINFO_DIR: returns the application directory

•	FILEINFO_PATH: returns the application complete path

•	FILEINFO_APPNAME: returns the application name

Example

Here is the MCI Send Command routine taken from the MCI object. You can insert macros where % % are replaced by the actual data.

short WINAPI DLLExport MCI_SendString(fprdata rdPtr, long param1, long param2)

{

fpchar	srce;

npchar	strBuf1 = 0;

npchar	strBuf2 = 0;

npchar	ptr, ptr1, ptr2;

short	flag, c1, c2, l;

srce = (fpchar)param1;

if (_fstrchr(srce, '%') != 0)

{

do

{

if ( (strBuf1 = (npchar)LocalAlloc(LPTR, 384)) == NULL )

break;

if ( (strBuf2 = (npchar)LocalAlloc(LPTR, 384)) == NULL )

break;

_fstrcpy(strBuf1, srce);

srce = (fpchar)strBuf1;

ptr1 = strchr(strBuf1, '%');

if (0 == ptr1)

break;

l = strlen(strBuf1);

if (l > 256)

break;

c1 = ptr1 - strBuf1;

ptr2 = strchr(ptr1 + 1,'%');

if (0 == ptr2)

break;

// Get the token

ptr2++;

c2 = ptr2 - strBuf1;

memcpy(strBuf2, ptr1, c2 - c1);

*(strBuf2 + (c2 - c1)) = 0;

flag = 0;

// Interpretation

if (0 == _stricmp(strBuf2, "%drive%"))

flag = FILEINFO_DRIVE;

else

if (0 == _stricmp(strBuf2, "%dir%"))

flag = FILEINFO_DIR;

else

if (0 == _stricmp(strBuf2, "%path%"))

flag = FILEINFO_PATH;

else

if (0 == _stricmp(strBuf2, "%appname%"))

flag = FILEINFO_APPNAME;

if (0 == flag)

break;

// Replace the string

ptr = strBuf2;

if (c1 != 0)

{

memcpy(ptr, strBuf1, c1);

ptr += c1;

}

callRun-timeFunction(rdPtr, RFUNCTION_GETFILEINFOS, (WORD)flag, (DWORD)((fpchar)ptr));

ptr += strlen(ptr);

memcpy(ptr, ptr2, l-c2);

strcpy(strBuf1, strBuf2);

}

while (TRUE);

}

// Stop sound device

if (rdPtr->rmciFlags & MCI_CLOSESOUND)

CloseSoundDevice(SP_WAVE);

// Send command

rdPtr->rmciError = (short)mciSendString((LPSTR)srce, rdPtr->rmciReturnString, sizeof(rdPtr->rmciReturnString), NULL);

if ( rdPtr->rmciError != 0 )

DisplayMCIError (rdPtr->rmciError);

// Free buffers

if (strBuf1 != 0)

LocalFree((HLOCAL)strBuf1);

if (strBuf2 != 0)

LocalFree((HLOCAL)strBuf2);

return 0;

}

 Related Topics


RFUNCTION_SUBCLASSWINDOW

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_SUBCLASSWINDOW, short wParam, short lParam);

Subclass the windows opened by the object to insert important data such as a pointer to the RUNDATA structure.

Parameters

short wParam: number of windows to subclass.

short lParam: eventual hook routine to branch on the window procedure, or 0.

Return value

None.

Comment

Please read the chapter How to control a window from an extension for more information.

 Related Topics


RFUNCTION_REDRAW

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_REDRAW, short wParam, short lParam);

Force a call of the DisplayRunObject routine during the display update process.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

If you don't use this routine, and if the HandleRunObject does not return the REFLAG_REDRAW flag, then DisplayRunObject will never be called.

Example

Look at the EDIT and CLOCK object.

 Related Topics


RFUNCTION_DESTROY

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_DESTROY, short wParam, short lParam);

Destroys the object.

Parameters

short wParam: not used.

short lParam: not used.

Return value

None.

Comment

After a call to this function, the object will be destroyed at the end of the current loop.

 Related Topics


RFUNCTION_GETSTRINGSPACE

callRun-timeFunction(LPRUNDATA rdPtr, short RFUNCTION_GETSTRINGSPACE, short wParam, short lParam);

Ask for space to store a string in Click & Create main buffers.

Parameters

short wParam: length needed.

short lParam: not used.

Return value

A pointer to the allocated area.

Comment

Warning: This is only temporary string space, the memory may be overwritten at next loop. You should simply use this routine to return the result of a string expression.

 Related Topics


CNCS graphic library


Overview: CNCS graphic library
CNCS graphic library

CNCS.DLL and CNCS32.DLL contain all of the core graphical routines for Corel Click & Create: graphical windows, sprites, image storing, background saving, but also sound and music routines. If your extension object needs to write anything on the screen, you need to use the functions provided.

For more information see the following:

 CNCS applications and windows

 Physical and logical windows

 How to draw in the frame window

 The run-time drawing process

 Drawing your object in edition-time

 Drawing your object in run-time

 Graphic functions

 Palette functions

 Images and DIBs functions

 Text and Font functions

 Other functions

 Related Topics


CNCS applications and windows


Overview: CNCS applications and windows
CNCS applications and windows

Two types of identifiers are used in almost every call to CNCS: application and window identifiers.

•	"npAppli idApp" identifies a CNCS application. A CNCS application can be considered as a group of memory banks. 3 banks: images, sounds and fonts.

•	"npWin idWin" identifies a CNCS window. CNCS windows are just like Windows' windows, with an extra feature added. You have the possibility of having sprites and graphical objects in the windows with background saving.

You have only to know the main objects used in Click & Create:

npAppli idAppli	the main CNCS application

npWin	idMainWin	the main window of the application

HWND	hMainWin	Windows handle of mainWin

npWin	idEditWin	the frame window (child of mainWin)

HWND	hEditWin	Windows handle of editWin

All of the graphic operations are done in the frame window. According to the CNCS function you use, you may also need to know the current graphic mode. This mode may have the following values:

SM_8	256 colors

SM_24	16 million of colors

SM_16	32768 colors

How to get these values:

Run-time: from the RunHeader structure:

fprh	rhPtr;

fpry	ryPtr;

rhPtr = rdPtr->rHo.hoAdRunHeader;

idAppli = rhPtr->rhIdAppli;

idMainWin = rhPtr->rhIdMainWin;

idEditWin = rhPtr->rhIdEditWin;

ryPtr = (fpry)((fpchar)rhPtr + rhPtr->rhyOffset);

scrMode = ryPtr->ryScrMode;

hMainWin = ryPtr->ryHmainWin;

hEditWin = ryPtr->ryHeditWin;

Edition-time: from the mv structure:

idAppli = knpV->mvIdAppli;

idMainWin = knpV->mvIdMainWin;

idEditWin = knpV->mvIdEditWin;

hMainWin = knpV->mvHMainWin;

hEditWin = knpV->mvHEditWin;

scrMode = knpV->mvScrMode;

 Related Topics


Physical and logical windows


Overview: Physical and logical windows
Physical and logical windows

The frame window consists in fact of two windows: the visible window which we call the physical window, and an invisible window which we call the logical window.

Corel Click & Create never writes in the physical window directly. Writing to this window is not necessary to obtain a flicker-free display despite a large number of sprites on the screen and objects and text that move in a Click & Create application. Instead of writing in the physical window directly, every operation is handled in the logical window, and when all the operations are over, at the end of the application loop, the zones of the logical window that have changed are copied into the physical window using the fastest routines possible.

 Related Topics


How to draw in the frame window


Overview: How to draw in the frame window
How to draw in the frame window

The frame window contains a physical and a logical screen. To display your object, you have the choice of two methods:

A) Use CNCS graphical functions

CNCS provides a number of handy functions that draw directly in the logical window and generate the proper update information so that your modifications are automatically copied into the physical window. These functions are:

WinGraphMode	= Windows SetBkMode function

WinGraphOp	= Windows SetROP2 function

WinPaper	= Windows SetBkColor function

WinPen	= Windows CreatePen function

WinLine	= Windows PolyLine function

WinRect	= Windows Rectangle function, with a null brush

WinFillBr	= Windows Rectangle function, with a null pen

It's not recommended to use these functions because:

•	they are not optimized for multiple successive calls,

•	they are very limited.

We have described the above functions in this document for your information only. We have included these function because they are used in the examples given in this development kit. However, you should use the following method:

B) Use Windows graphical functions

Using the Windows graphical function is a more complicated way of programming. However using this method, you will have access to all of Windows graphical API.

Follow the following procedure:

1.	Get the handle of the logical window DC with the WinGetHDCLog function

2.	Use Windows API functions with DC handle

3.	Release the DC with the WinReleaseHDCLog function

4.	Indicate to Corel Click & Create that it should copy the modified zone from the logical window to the physical window with the functions WinAddZone.

Example: fill the whole frame window:

HWND	hWin;

HDC	hdc;

RECT	rc;

if ( (hdc = WinGetHDCLog (idEditWin)) != NULL )

{

hWin = WinGetHandle (idEditWin);

GetClientRect (hWin, &rc);

if ( (hp = GetStockObject (NULL_PEN)) != NULL )

{

hop = SelectObject (hdc, hp);

if ( (hb = CreateSolidBrush (RGB(0xFF,0x00,0x00))) != NULL )

{

hob = SelectObject (hdc, hb);

Rectangle (hdc, 0, 0, rc.right, rc.bottom);

SelectObject (hdc, hob);

DeleteObject (hb);

WinAddZone (idEditWin, &rc);

}

SelectObject (hdc, hop);

}

WinReleaseHDCLog (idEditWin, hdc);

}

 Related Topics


The run-time drawing process


Overview: The run-time drawing process
The run-time drawing process

For your information, and so that you fully understand how the system works, we have included a step by step list of what Corel Click & Create does to display an application with a complex screen made of sprites, backgrounds, texts, etc. and a multitude of other objects that overlap each other.

1.	At the beginning of the application, all the background objects are drawn in the logical screen, respecting the order of priority.

2.	The application begins its first loop. At the end of the first loop, the update process begins

3.	First, the quickdisplay objects, if they exist in the application save the content of the logical window beneath them in a memory buffer.

4.	All the sprites do the same.

5.	All the quickdisplay objects drawn themselves into the logical screen, respecting the order of priority (well, in inverse order, so that the last to be drawn is actually the object of highest priority)

6.	All the sprites are drawn in the same manner.

7.	Now, the display is complete in the logical window: Corel Click & Create copy it as fast as possible in the physical window, and eventually zoom or reduces the size of the window when transferring, if the checkmark Zoom to window size is set in the application setup.

8.	Now comes another loop of the application. At the end of this loop:

9.	Corel Click & Create check which quickdisplay object has changed. Only the ones that have changed, or the ones overlapping some others that have changed, are asked to restore the background behind them by transferring the memory buffer created at step 3 back into the logical window.

10.	All the sprites do the same.

11.	The quickdisplays objects that have changed are now asked to save the background behind their new position

12.	All the sprites save the background behind their new position

13.	The quickdisplays that have changed now draw themselves into the logical window

14.	All the sprites do the same

15.	The modified zones from the logical window are transferred into the physical window

16.	A new loop of the application happens, and we're back at step 9!

 Related Topics


Drawing your object in edition-time


Overview: Drawing your object in edition-time
Drawing your object in edition-time

The EditorDisplay routine only has to use one of the two methods described earlier in How to draw in the frame window to be displayed in the frame window in edition-time.

 Related Topics


Drawing your object in run-time


Overview: Drawing your object in run-time
Drawing your object in run-time

An extension object that has to take care of:

•	Saving the background

•	Drawing

•	Restoring the background

99% of the objects should leave the background saving and restoring operations to Corel Click & Create.

It is only if you specify the OEFLAG_INTERNALBACKSAVE flag in your OEFLAGS fields that you will have to implement the three routines in charge of this process SaveBackgound, RestoreBackground and KillBackground.

 Related Topics


Graphic functions


Overview: Graphic functions
Graphic functions

The available graphic functions are:

•	 WinGetHandle

•	 WinGetHDC

•	 WinReleaseHDC

•	 WinGetHDCLog

•	 WinReleaseHDCLog

•	 WinGetLogRect

•	 WinClip

•	 WinPaper

•	 WinPen

•	 WinGraphMode

•	 WinGraphOp

•	 WinPlot

•	 WinLine

•	 WinRect

•	 WinFillRect

•	 WinFillBr

•	 WinGradRect

•	 WinScroll

•	 WinAddZone

•	 SaveRect

•	 RestoreRect

 Related Topics


WinGetHandle

HWND	WINAPI WinGetHandle	(npWin idWin)

Parameters

idWin: CNCS window

Return value

Returns the Windows handle of a CNCS window.

 Related Topics


WinGetHDC

HDC WINAPI WinGetHDC (npWin idWin)

Parameters

idWin: CNCS window

Return value

Returns the handle of a device context related to the physical screen of a CNCS window. This device context can be used for drawing with Windows functions.

Comments

The device context must be released with WinReleaseHDC.

 Related Topics


WinReleaseHDC

void WINAPI WinReleaseHDC (npWin idWin, HDC hdc)

Parameters

idWin:	CNCS window

hdc:	device context

Effect

Release a device context related to the physical screen of a CNCS window.

 Related Topics


WinGetHDCLog

HDC WINAPI WinGetHDCLog (npWin idWin)

Parameters

idWin:	CNCS window

Return value

Returns the handle of a device context related to the logical window of a CNCS window. This device context can be used for drawing with Windows functions.

Comment

The device context must be released with WinReleaseHDCLog.

 Related Topics


WinReleaseHDCLog

void WINAPI WinReleaseHDCLog (npWin idWin, HDC hdc)

Parameters

idWin:	CNCS window

hdc:	device context

Effect

Releases a device context related to the logical screen of a CNCS window.

 Related Topics


WinGetLogRect

void WINAPI WinGetLogRect (npWin idWin, RECT FAR *rc)

Parameters

idWin: CNCS window

rc: rectangle

Effect

Fills the rc structure with the size of the logical screen of a CNCS window. (rc->left = rc->top = 0, rc->right=width, rc->bottom=height).

 Related Topics


WinClip

void WINAPI WinClip (npWin idWin, int x1, int y1, int x2, int y2)

Parameters

idWin: 	CNCS window

x1:	left

y1: 	top

x2: 	right

y2: 	bottom

Effect

Sets the clipping rectangle for the following functions: WinFillRect, WinFillBr, WinGradRect, WinRect, WinPlot, PasteSprite, PasteSpriteEffect.

 Related Topics


WinPaper

void WINAPI WinPaper (npWin idWin, COLORREF color)

Parameters

idWin: CNCS window

color: background color

Effect

Sets the background color. Calls the Windows function SetBkColor.

Comment

Using this function is not recommended.

 Related Topics


WinPen

void WINAPI WinPen (npWin idWin, COLORREF color, int style, int width)

Parameters

idWin: 	CNCS window

color: 	pen color

style: 	pen style (see CreatePen function)

width: 	pen width (see CreatePen function)

Effect

Creates a pen for use with WinRect and WinLine.

Comment

Using this function is not recommended.

 Related Topics


WinGraphMode

void WINAPI WinGraphMode (npWin idWin, int grMode)

Parameters

idWin:	CNCS window

grMode: background mode (OPAQUE / TRANSPARENT).

Effect

Sets the background mode. Calls the Windows function SetBkMode.

Comment

Using this function is not recommended.

 Related Topics


WinGraphOp

void WINAPI WinGraphOp (npWin idWin, int grOp)

Parameters

idWin:	CNCS window

grOp: 	drawing mode (see Windows function SetROP2)

Effect

Sets the drawing mode. Calls the Windows function SetROP2.

Comment

Using this function is not recommended.

 Related Topics


WinPlot

void WINAPI WinPlot (npWin idWin, short x, short y, COLORREF color)

Parameters

idWin:	CNCS window

x:	x coordinate

y:	y coordinate

color:	pixel color

Effect

Sets a pixel in the logical screen of a CNCS window using a solid color.

Comment

This function doesn't call any Windows function. The device context of the logical screen must be released before calling this function.

 Related Topics


WinLine

void WINAPI WinLine (npWin idWin, POINT FAR *pt, UINT nPoints)

Parameters

idWin:	CNCS window

pt:	table of POINTs

nPoints:	number of points in the table

Effect

Draws a polyline. Calls the Windows function PolyLine (see this function for the parameters).

Comment

Using this function is not recommended.

 Related Topics


WinRect

void	WINAPI WinRect (npWin idWin, RECT FAR *rc)

Parameters

idWin:	CNCS window

rc:	rectangle

Effect

Draws a rectangle. Calls the Windows function rectangle, with a NULL brush. Uses the current pen created by WinPen.

Comment

Using this function is not recommended.

 Related Topics


WinFillRect

void WINAPI WinFillRect (npWin idWin, int x1, int y1, int x2, int y2, COLORREF color)

Parameters

idWin:	CNCS window

x1: 	left

y1: 	top

x2: 	right

y2: 	bottom

color: 	color

Effect

Fills a rectangle, using the specified color.

Comment

This function doesn't call any Windows function. The device context of the logical screen must be released before calling this function.

 Related Topics


WinFillBr

void WINAPI WinFillBr (npWin idWin, int x1, int y1, int x2, int y2, HBRUSH hbr)

Parameters

idWin:	CNCS window

x1:	left

y1:	top

x2:	right

y2:	bottom

hbr:	Windows HBRUSH

Effect

Fills a rectangle, using the specified brush.

Comment

Using this function is not recommended.

 Related Topics


WinGradRect

void WINAPI WinGradRect (npWin idWin, short x1, short y1, short x2, short y2, DWORD color1, DWORD color2, short flags);

Parameters

idWin:	CNCS window

x1:	left

y1:	top

x2:	right

y2:	bottom

color1:	start color

color2:	end color

flags:

GRADIENT_HORZ	horizontal

GRADIENT_PATTERN	use Windows pattern

Effect

Fills a rectangle, using a gradient.

Comment

The device context of the logical screen must be released before calling this function.

 Related Topics


WinScroll

int WINAPI WinScroll (npWin idWin, short xDest, short yDest, short xSrc, short ySrc, WORD width, WORD height);

Parameters

idWin:	CNCS window

xDest, yDest:	top-left corner of the destination rectangle

xSrc, ySrc:	top-left corner of the source rectangle

width:	width of the source rectangle

height:	height of the source rectangle

Effect

Moves a rectangle in the logical window. (Doesn't call WinAddZone).

Comment

Using this function is not recommended because this function could interfere with the general handling of Click & Create. The device context of the logical screen must be released before calling this function.

 Related Topics


WinAddZone

void	WINAPI WinAddZone (npWin idWin, RECT FAR *rc);

Parameters

idWin:	CNCS window

rc:	rectangle

Effect

Adds a rectangle to the list of areas to copy from the logical screen to the physical window. The areas will be copied at the end of the current main Click & Create loop.

 Related Topics


SaveRect

int WINAPI SaveRect (npWin idWin, WORD segPtr, DWORD offPtr, short x1, short y1, short x2, short y2);

Parameters

idWin:	CNCS window

segPtr, offPtr: 	huge pointer (segment+long offset) on the following structure:

{

HGLOBAL	hgZone;

LPBYTE	adZone;

RECT	rcZone;

};

In 32 bit mode, segPtr is ignored, the pointer is given by offPtr.

x1, y1:	top-left corner of the zone to save

x2, y2:	bottom-right corner (not included) of the zone to save

Effect

Saves a zone of the logical screen. This function allocates a memory block, copies its HGLOBAL handle and its address into the 6 first bytes of the structure, and stores the rectangle coordinates in rcZone. This structure is used by the function RestoreRect.

Return value

Returns 0 if OK.

Comment

The device context of the logical screen must be released before calling this function.

 Related Topics


RestoreRect

void WINAPI RestoreRect (npWin idWin, WORD segPtr, DWORD offPtr)

Parameters

idWin:	CNCS window

segPtr, offPtr:	see function SaveRect.

Effect

Restores a zone of a logical screen saved by SaveRect.

Comment

The device context of the logical screen must be released before calling this function.

 Related Topics


Palette functions


Overview: Palette functions
Palette functions

The available palette functions are:

•	 GetKnpPalette

•	 GetNearestIndex

•	 GetRGB

•	 GetOpaqueBlack

 Related Topics


GetKnpPalette

int WINAPI GetKnpPalette (LOGPALETTE FAR *dest, int mode, npAppli idApp);

Parameters

dest	destination buffer

mode	graphic mode

idApp	CNCS application

Effect

Fills the LOGPALETTE structure with the current palette of the CNCS application.

Return value

Number of copied colors, 0 if true color mode.

Example

nbColors = GetKnpPalette (buffer, scrMode, idAppli);

 Related Topics


GetNearestIndex

int WINAPI GetNearestIndex (npAppli idApp, int mode, COLORREF color);

Parameters

idApp 	CNCS application

mode 	graphic mode

color 	color

Effect

Finds the index of the nearest matching color in the palette of the application.

Return value

Color index, -1 if true color mode.

Example

ind = GetNearestIndex (idAppli, scrMode, 0xFF0000);

 Related Topics


GetRGB

COLORREF WINAPI GetRGB (npAppli idApp, int mode, int index);

Parameters

idApp 	CNCS application

mode 	graphic mode

index 	color index

Effect

Returns the RGB values of a color index in the palette of the application.

Return value

RGB value.

Example

if ( scrMode == SM_8 )

color = GetRGB (idAppli, SM_8, 2);

 Related Topics


GetOpaqueBlack

int WINAPI GetOpaqueBlack (npAppli idApp)

Parameters

idApp 	CNCS application

Effect

In 256 color mode, return the index of the non-transparent black.

Return value

Index.

Example

if ( scrMode == SM_8 )

opb = GetOpaqueBlack (idApp);

 Related Topics


Images and DIBs functions


Overview: Images and DIBs functions
Images and DIBs functions

The available image and DIBs functions are:

•	 InitDibHeader

•	 FillDib

•	 DibToImageEx

•	 DibToImage

•	 DelImage

•	 ImagetoDib

•	 RemapDib

•	 PasteSprite

•	 PasteSpriteEffect

 Related Topics


InitDibHeader

DWORD WINAPI InitDibHeader (npAppli idApp, int mode, int width, int height, BITMAPINFO FAR *dib);

Parameters

idApp:	CNCS application

mode:	graphic mode (SM_8 or SM_24)

width:	DIB width

height:	DIB height

dib:	DIB address

Effect

Initializes the header of a DIB (256 colors or 16 million of colors).

Return

Size of buffer if dib is NULL.

 Related Topics


FillDib

void	WINAPI FillDib (BITMAPINFO FAR *dib, COLORREF color);

Parameters

dib: DIB address

color: color used to fill the DIB

Effect

Fills a DIB with a solid color.

 Related Topics


DibToImageEx

WORD	WINAPI DibToImageEx (npAppli idApp, fpImg imgHeader, BITMAPINFOHEADER FAR *dib, WORD flags);

Parameters

idApp: 	CNCS application

imgHeader: 	image header. Only the hot spot and action point coordinates are used.

dib:	DIB address

flags:

AI_COMPARE	compare the DIB with the existing images

AI_ACE	compress the transparent pixels.

Effect

Creates an image from a device independent bitmap.

Warning: the bitmap is not remapped to the current palette. If the DIB palette is different from the current palette, you must use the function RemapDib before to using DibToImageEx.

Return value

Image number, 0 if error.

Note: when you have no longer need of the image, you must delete it using the DelImage function.

 Related Topics


DibToImage

WORD	WINAPI DibToImage (npAppli idApp, fpImg imgHeader, BITMAPINFOHEADER FAR *dib);

Same as the DibToImageEx function, but without the flags.

 Related Topics


DelImage

int WINAPI DelImage (npAppli idApp, WORD img);

Parameters

idApp: 	CNCS application

img: 	image number

Effect

Delete an image created by DibToImage.

 Related Topics


ImagetoDib

DWORD WINAPI ImageToDib (npAppli idApp, WORD img, WORD mode, LPBYTE dib);

Parameters

idApp: CNCS application

img: image number

mode: DIB graphic mode:

0 : DIB mode = image mode

SM_8 : the image will be converted into 256 colors

SM_24 : the image will be converted into 16 million of colors

dib: DIB address

Effect

Convert an image into a DIB.

Return value

Size of the DIB if dib is NULL.

 Related Topics


RemapDib

void	WINAPI RemapDib (BITMAPINFO FAR *dib, npAppli idApp, LPBYTE reserved);

Parameters

dib: DIB address

idApp: CNCS application

Effect:

Remap a DIB using the palette of a CNCS application.

 Related Topics


PasteSprite

void	WINAPI PasteSprite (npWin idWin, WORD img, short x, short y, WORD flags);

Parameters

idWin: 	CNCS window (must have a logical screen).

img: 	image number.

x:	x coordinate.

y:	y coordinate.

flags:

PSF_HOTSPOT	Take hot spot into account

PSF_NOTRANSP	Paste image in opaque mode

Effect

Paste an image into the logical screen of a window.

 Related Topics


PasteSpriteEffect

void	WINAPI PasteSpriteEffect (npWin idWin, WORD img, short x, short y, WORD flags, DWORD effect, DWORD effectParam);

Parameters

idWin:	 CNCS window (must have a logical screen).

img: 	image number

x:	x coordinate

y:	y coordinate

flags:

PSF_HOTSPOT	Take hot spot into account

effect: 	special effect:

EFFECT_TRANSP	Transparent

EFFECT_OPAQUE	Opaque

EFFECT_SEMITRANSP	Semi-transparent, effectParam = coefficient (0 -> 100)

EFFECT_INVERTED	Inverse

EFFECT_XOR	XOR

EFFECT_AND	AND

EFFECT_OR	OR

effectParam: only if effect == EFFECT_SEMITRANSP.

Effect:

Paste an image into the logical screen of a window, using special effects.

 Related Topics


Text and Font functions


Overview: Text and Font functions
Text and Font functions

In the functions described below, AddFont, DelFont, GetFontInfos, WinCreateFont can be totally ignored. They are mentioned in this file because they are used in some examples, but you can work without these functions.

The size of the LOGFONT structure is not the same in the 16 and 32 bit versions of Windows. When LOGFONT structures are used in extensions, only the 16-bit structure (called LOGFONT16) is stored in the object. In 32-bit mode some additional functions allow to use and convert 16 and 32 bit LOGFONT structures.

The available text and font functions are:

•	 AddFont

•	 DelFont

•	 GetFontInfos

•	 WinCreateFont

•	 WinPasteText

•	 LogFont32to16

•	 CreateFontindirect16

 Related Topics


AddFont

WORD	WINAPI AddFont (npAppli idApp, WORD flags, fpFont fpf, LPWORD reserved1, WORD reserved2);

Parameters

idApp: 	CNCS application

flags:	must be FTYPE_WINDOWS

fpf:	address of Font structure

Effect

Add a font to the fonts of a CNCS application.

Return value

Font number, 0 if error.

32-bit only

In 32-bit mode, the following function uses the 16-bit LOGFONT16 structure:

WORD	WINAPI AddFont16 (npAppli idApp, WORD flags, fpFont16 fpf, LPWORD res1, WORD res2);

In 16-bit mode, AddFont16 = AddFont.

 Related Topics


DelFont

int WINAPI DelFont (npAppli idApp, WORD nFont);

Parameters

idApp: 	CNCS application

nFont: 	font number

Effect

Delete a font created by AddFont.

 Related Topics


GetFontInfos

int WINAPI GetFontInfos 	(npAppli idApp, WORD nFont, fpFont fpf, LPWORD reserved);

Parameters

idApp:	CNCS application

nFont: 	font number

fpf: 	address of Font structure

Effect

Fills the fpf structure with the characteristics of the specified font.

32-bit only

In 32-bit mode, the following function uses the 16 bit LOGFONT16 structure:

int WINAPI GetFontInfos16	(npAppli idApp, WORD nFont, fpFont16 fpf, LPWORD reserved);

In 16-bit mode, GetFontInfos16 = GetFontInfos.

 Related Topics


WinCreateFont

HFONT	WINAPI WinCreateFont (npAppli idApp, WORD nFont);

Parameters

idApp: 	CNCS application

nFont: 	font number

Effect

Create a Windows font from a CNCS font.

Return value

HFONT, NULL if error.

 Related Topics


WinPasteText

int WINAPI WinPasteText	(npWin idWin, HFONT hFnt, RECT FAR *rc, LPSTR szString, COLORREF color, WORD flags);

Parameters

idWin: 	CNCS window

hFnt: 	Windows HFONT

rc: 	rectangle

szString: null-terminated string

color: 	text color

flags: 	same flags as the Windows DrawText function

Effect

Draws a text in a logical screen.

Return value

Text height.

Comment

This function calls DrawText, so you could call WinGetHDCLog, DrawText, WinReleaseHDCLog and WinAddZone.

This works fine in 32-bit mode, but in 16-bit mode you must call WinPasteText because DrawText doesn't work in the logical screens in 16-bit standard graphic mode.

Example

LOGFONT	lf;

HFONT	hFnt;

RECT	rc;

...

hFnt = CreateFontIndirect (&lf);

WinPasteText (idEditWin, hFnt, &rc, "Hello", RGB(0xFF,0,0), DT_SINGLELINE);

DeleteObject (hFnt);

 Related Topics


LogFont32to16

void WINAPI LogFont16To32 ( LOGFONT FAR * lf32, LOGFONT16 FAR * lf16 );

Parameters

lf16: 	address of LOGFONT16 structure

lf32: 	address of LOGFONT structure

Effect

Convert a LOGFONT16 structure from 32- to 16-bit.

Comment:

32-bit only.

 Related Topics


CreateFontindirect16

HFONT	WINAPI CreateFontIndirect16 ( LOGFONT16 FAR * lFont );

This is the Windows CreateFontIndirect function, using a 16-bit LOGFONT structure.

 Related Topics


Other functions


Overview: Other functions
Other functions

Some other functions that are available are:

•	 DialOpen

•	 CloseSoundDevice

•	 EnumFile

 Related Topics


DialOpen

npDial	WINAPI DialOpen	(HINSTANCE hInst, LPCSTR dialTempName, HWND hWin, FARPROC proc, DWORD reserved, LPCSTR reserved2, int flags, LPARAM lParam);

Parameters

hInst: 	HINSTANCE of the application

dialTempName: dialog box template name

hWin: 	parent window

proc: 	dialog procedure

flags:	DL_MODAL associated (or not) with one of the following values:

DL_CENTER_WINDOW	=> center the dialog in the parent window

DL_CENTER_SCREEN	=> center the dialog in the screen

lParam: lParam value passed to the WM_INITDIALOG message.

Effect

Open a 3-D style modal dialog box, even under Windows 3.1 or Windows NT 3.51.

Return value

NPDIAL_ERROR if error.

Comment

This function calls DialogBoxParam.

 Related Topics


CloseSoundDevice

void	WINAPI CloseSoundDevice (WORD flg);

Parameters

flg: 	must be SP_WAVE

Effect

Close the sound device. Must be used before you open/use/close the sound device.

 Related Topics


EnumFile

int WINAPI EnumFile (LPSTR path, LPSTR fileType, int subDirs, int (WINAPI * proc) (LPSTR));

Parameters

path: 	source directory

fileType: 	type of the files to enumerate

subDirs: 	0 = do not include subdirectories, 1 = include subdirectories

proc	procedure called for each file:

Parameter = fileName

Return value:0 = continue enumerating, ! = 0 = error and stop enumerating.

Effect

Enumerates the files located in the specified directory.

Return value

Returns the code returned by the called procedure.

Example

int WINAPI enumProc ( LPSTR fileName )

{

return 0;

}

...

EnumFile ("c:\\", "*.txt", 1, enumProc);

 Related Topics