星期四, 6月 24, 2004

OLE Drag and Drop Sample Applications

http://www.unitoops.com/uoole/examples/

Sample Application: CPPOutlookTest.cpp


First: C++Builder

C++Builder programs consist of a project source code file, one or more source code unit files, a unit header file, and other files that you probably won't edit directly. The project source contains the main program, which is created automatically and usually does nothing more than call the application's Initialize(), CreateForm(), and Run() methods. Unit source code files contain the program's functions, procedures, and event handlers. C++Builder's visual environment and class library handle many of the traditional Windows programming details such as setting up the window class, the window procedure, and the message loop.

Here is the C++Builder project source code file for our first example program:


/***************************************************************************** *
* First.cpp *
* FirstU.cpp *
* *
* This is the first Fastgraph for Windows example program. It demonstrates *
* tasks common to most Fastgraph for Windows programs and serves as a *
* template for building the other examples. *
* *
\****************************************************************************/
#include
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("FirstU.cpp", Form1);
USERES("First.res");
USELIB("FGWBC32.LIB");
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}

Note how the project source code file includes a USELIB statement referencing Fastgraph's Borland C++ library (FGWBC32.LIB). This is included automatically when you add the library file to your project in the C++Builder IDE. Also, note the USEFORM statement that references the FirstU.cpp unit source code file, which in turn includes the FirstU.h unit header file. This is likewise added automatically when you create the project.

The FirstU.cpp unit source code file contains an #include directive to include the FirstU.h unit header file. Near the beginning of the unit header file, we add another #include directive referencing Fastgraph's FGwin.h header file. The user declarations section of the unit header file is a good place to define global variables used in the event handlers of the unit source code file. C++Builder automatically creates and maintains the rest of the unit header file for you. The FirstU.h unit header file is shown here:


//---------------------------------------------------------------------------
#ifndef FirstUH
#define FirstUH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall FormActivate(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormPaint(TObject *Sender);
void __fastcall FormResize(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
HDC hDC;
HPALETTE hPal;
int hVB;
UINT cxClient, cyClient;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

And here is the FirstU.cpp unit source code file, which contains our event handlers:


/***************************************************************************** *
* First.cpp *
* FirstU.cpp *
* *
* This is the first Fastgraph for Windows example program. It demonstrates *
* tasks common to most Fastgraph for Windows programs and serves as a *
* template for building the other examples. *
* *
\****************************************************************************/
#include
#pragma hdrstop
#include "FirstU.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
fg_realize(hPal);
Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
hDC = GetDC(Form1->Handle);
fg_setdc(hDC);
hPal = fg_defpal();
fg_realize(hPal);
fg_vbinit();
hVB = fg_vballoc(640,480);
fg_vbopen(hVB);
fg_vbcolors();
fg_setcolor(19);
fg_fillpage();
Application->OnActivate = OnActivate;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
fg_vbscale(0,fg_getmaxx(),0,fg_getmaxy(),0,cxClient-1,0,cyClient-1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
cxClient = ClientWidth;
cyClient = ClientHeight;
Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
fg_vbclose();
fg_vbfree(hVB);
fg_vbfin();
DeleteObject(hPal);
ReleaseDC(Form1->Handle,hDC);
}

The FirstU.cpp unit is essentially made up of event-handling procedures that provide our first look at some Fastgraph functions. Note that our program does not explicitly call the event procedures. Instead, they are called by C++Builder's class library in response to Windows events such as creating or resizing the window (these procedures are analogous to the traditional WindowProc() message handlers). Our program includes event handlers for the form's OnCreate, OnActivate, OnPaint, OnResize, and OnDestroy events. You can use C++Builder's Object Inspector to generate code templates for these form event handlers.

An OnCreate event occurs when the form is first created during program execution. This event occurs once per program instance and is analogous to the WM_CREATE Windows message. Hence, it is a good place for any application-specific initialization code. Our OnCreate handler is in the FormCreate() procedure and first calls the Windows API function GetDC() to obtain a device context to the form's client area. It then calls fg_setdc() to make the device context available to other Fastgraph functions:


hDC = GetDC(Form1->Handle);
fg_setdc(hDC);

Next, it creates and realizes the default logical palette:


hPal = fg_defpal();
fg_realize(hPal);

The OnCreate handler then initializes Fastgraph's virtual buffer environment, creates a 640x480 virtual buffer and makes it the active virtual buffer, and assigns the logical palette colors to the virtual buffer:


fg_vbinit();
hVB = fg_vballoc(640,480);
fg_vbopen(hVB);
fg_vbcolors();

Next, we fill the virtual buffer with blue pixels (color 19 is blue when using Fastgraph's default 256-color virtual buffers with the default logical palette):


fg_setcolor(19);
fg_fillpage();

The last thing the OnCreate event handler does is set up the pointer to the application's OnActivate handler:


Application->OnActivate = OnActivate;

The application's OnActivate handler (which has a different purpose than the form's OnActivate handler) executes when the program gains the input focus. This happens when control shifts from another Windows application to our program, so it is thus analogous to the WM_SETFOCUS Windows message. Because we want the application's OnActivate handler to perform the same tasks as the form's OnActivate handler, we simply point the application's handler to the form's handler. The form's OnActivate handler, and hence the application's OnActivate handler, first calls fg_realize() to activate the program's logical palette (in case another program has changed the logical palette colors). It then calls C++Builder's Invalidate() function to force an OnPaint event to redraw the form's client area. This sequence is typical of OnActivate event handlers in Fastgraph programs.

An OnPaint event occurs when the form's client area must be repainted; it is analogous to the WM_PAINT Windows message. Our OnPaint handler is in the FormPaint() procedure and just calls fg_vbscale() to display the contents of the 640x480 virtual buffer scaled to the size of the form's client area. This sequence is typical of OnPaint event handlers in Fastgraph programs.

You can remove the OnActivate event handler by calling fg_realize() before fg_vbscale() in the OnPaint handler. While this eliminates the work of manually creating an application event handler, it introduces overhead in OnPaint because it must realize the logical palette every time the form is repainted. This wouldn't be noticeable in a simple program like our first example. However, in games or other applications where we frequently update the form (and hence frequently execute the OnPaint handler), we recommend using a separate OnActivate handler that realizes the logical palette only when needed.

An OnResize event occurs whenever the size of the form changes, and also upon creation of a form. It is analogous to the WM_SIZE Windows message. Our OnResize handler is in the FormResize() procedure and simply saves the new width and height of the client area (in pixels) in the variables cxClient and cyClient. These quantities are passed to fg_vbscale() in the OnPaint event handler.

An OnDestroy event occurs after removing a form and often signals a program exit; it is analogous to the WM_DESTROY Windows message. Our OnDestroy handler is in the FormDestroy() procedure and first closes the virtual buffer, releases its memory, and terminates virtual buffer processing:


fg_vbclose();
fg_vbfree(hVB);
fg_vbfin();

It then calls two Windows API functions to delete the logical palette created with fg_defpal() and release the device context created with GetDC():


DeleteObject(hPal);
ReleaseDC(Form1->Handle,hDC);

Each C++Builder example supplied with Fastgraph consists of six files comprising a C++Builder project. The unit source code, unit header, and graphical form files will have the same name as the Fastgraph example, but with the letter "U" appended to the file name. For example, the six files for the First example project are:


First.cpp
project source code file

First.mak
project make file

First.res
project resource file

FirstU.cpp
unit source code file

FirstU.h
unit header file

FirstU.dfm
graphical form file



In general, we'll only be working with the unit source code and header files for each project, as they contain the event handling procedures and their global variables. We'll let C++Builder's visual programming environment handle the maintenance of the other files. For more information about these files, please consult your C++Builder manuals.


<< Prev
Next >>






Contents
Fastgraph Home Page


copyright 2001 Ted Gruber Software, Inc.

Application Development

This discussion is currently limited to the Intel-based compiler. All arguments are widened to 32-bits when passed to functions. Return values are 32-bits and are returned in EAX, except 8 byte structures returned in

EAX: EDX. The 32-bit C compiler provides several ways to call functions, but the pascal _fortran and _syscall conventions are obsolete. Supported calling conventions for functions are defined by the keywords:

_cdeclDefault C calling convention. Caller cleans up stack, so vararg functions are supported. Arguments pushed on stack right to left. _cdecl 1 functions prefixed by when decorated.

_stdcall Stacked cleaned up by called function, so compiler makes vararg functions cdec 1, and a function prototype is required. Arguments pushed on stack right to left and function is prefixed with _ and postfixed with @x when decorated, where x is the number of bytes to be pushed on the stack. Faster calling and smaller code than for _cdecl, if number of function calls > number of functions.

_fastcall Similar to _stdcall but speeds up call by storing at most two arguments in EAX and EDX.

All other arguments pushed as for _stdcall. Functions are prefixed with @ and postfixed with @x when decorated, where x is the number of bytes to be pushed on the stack..
These are also controlled for entire source files by the /Gd, /Gz, and /Gr options respectively.

The strict calling convention for Windows functions generally is WINAPI, and CALLBACK for user-defined callbacks. Both were defined to be FAR (far) PASCAL (pascal) in the Windows 3.x API, passing parameters in left to right order, and tidying the stack by removing their arguments before passing control back to the calling environment. They are invoked by a far call, and pointers passed as arguments are far pointers.

In contrast, Win32 API functions and user-defined callbacks use the _stdcall calling convention as

PASCAL,WINAPI, CALLBACKetc are defined to be _stdcall. Functions are invoked by a near call, and addresses passed as arguments are always near pointers. FAR has been defined to nothing. The /Zf option on the compiler ignores the _far keyword, which aids I 6->32-bit portability. The compiler still allows the .._pascal keyword for pascal calling convention, so watch out if you���ve defined any callbacks using pascal explicitly. Pascal calling convention is callee cleans up stack, arguments pushed left to right.


The development cycle for 32-bit graphical or console applications follows an established pattern; source code written in assembler or a high level language is compiled or assembled to give object code, which is linked with libraries and run-time support modules to produce a final executable file. 32-bit Graphical Windows applications may also need to compile resource scripts into binary form and link them into the executable.

Visual C++ 6.0 provides a complete Windows NT based 32-bit development environment; source and resource editors, compiler, linker, librarian, debugger and resource compiler.

In order to make use of Win32��� s advanced features, however, the source code must invoke the 32-bit Windows API functions, and should #include the windows.h file, which will in turn #include the appropriate 32-bit header files. The source code can also use standard C library functions.

For those familiar with the process of building applications and DLLs for Windows 3.x, there are some differences. Resources are linked along with object modules and libraries. You do not run the resource compiler to add resources to the executable file. Use CVTRES to convert a resource file to a linkable object file.


The Message Compiler, mc.exe, converts ASCII message text (.mc) source tiles into binary tiles containing a message table resource for inclusion in a resource script (.rc) file. The source-format supports multiple versions of the same message text, one for each national language supported, thus allowing support for multiple languages within the same image file.. Mc.exe automatically assigns numbers to each message, and generates a C/C++ include file for use by the application to access a message using a symbolic constant. For each Language statement, it generates a binary file containing a message table resource. It also generates a single resource script file that contains the appropriate Resource Compiler statements to include each binary output file as a resource with the appropriate symbolic name and language type.

Applications that perform event logging typically use an independent resource-only DLL that contains the messages, rather than carry the messages in the application image. This DLL is then specified as the source of message text for the events that it logs, when using the event logging APIs or

FormatMessage() to retrieve and use the message text.

The Win32 API is complex and it is essential that programmers routinely check the return value for each function invoked, and check error codes. Win32 functions return an expected result or tell you if an error has occurred; they don���t always indicate what the error was, e.g. CreateWindow() returns an HWND or NULL. However, the Win32 APIs do record errors on a per-thread basis, which can be obtained with GetLastError(),FormatMessage() allows the conversion of error codes, including those returned by GetLastError() into error strings. E.g.

LPVOID lpMessageBuffer;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), LANG_USER_DEFAULT, (LPSTR)&lpMessageBuffer, 0, NULL);

/* display this string */
LocalFree( (HLOCAL) lpMessageBuffer
Visual C++ 6.0 has a built in debugger which is very good! It supports Just In Time debugging which allows you to build your app for debug, run it and when it crashes VC++ will catch the error and jump to the source line that caused the problem.

Ntsd is a good deal less user friendly and allows debugging from a second machine. It is symdeb-like and accepts text-based commands to step through the debugging process. It supports multi-threaded debugging and also multi-process debugging. Both Ntsd and WinDbg are user mode programs, and allow source-level and machine-level debugging. At a later date, a remote debugging capability will be added to WinDbg, obviating the need for Ntsd.

Kd is a kernel mode remote debugger that runs on a separate NT hosted computer. It provides assembly language debugging of kernel mode code and is intended for system developers and device driver developers. It also supports multi-processor debugging. Ntsd and Kd share much of the same syntax. However Kd is not well suited to debugging user mode code; it does not provide support for threads, cannot set breakpoints in user mode code and cannot be used to examine paged-out memory.

The /DEBUGTYPE COFF flag must be used in the linker options to create debugging information for the Ntsd.exe and Kd.exe debuggers.

Windbg is another windows-hosted debugger similar to Visual C++.
An automated porting tool, Porttool.exe, comes with Visual C++ and assists in porting 16-bit applications to 32-bit applications. It parses source files and uses a table driven search facility to find and highlight non-portable program elements, describe the problem, and where appropriate, offers alternatives.

The Pview.exe process viewer allows the examination and modification of processes and threads running on the system. It indicates how much memory is being used, and how much of it is paged. It reports which processes and threads are using most CPU time. It allows the examination of how threads run at different priorities, and reports on thread status. It also reports thread API usage. Because Pview allows the modification of thread and process state, it has the potential for causing serious disruption to the system!

Spy++.exe is similar to that for Windows 3.x, and allows the monitoring of messages, and associated parameters, being transmitted around the system. It also allows monitoring of processes and threads.

Ddespy.exe, is also similar to that for Windows 3.x, and allows the examination of client and server DDE activity.

AnsiString Add

AnsiString demo;
demo=(ansiStrinng)"string1"+"string2";
ShowMessage(demo);

demo+="String"; //��航炊隤�瘜�