|
Well, that very much depends on the structure of your app. Usually, it is better to have the plugins provide the functionality and data and let the app itself control the GUI (for instance, the plugin can provide a command name and a command callback and it is the responsibility of the app to insert the command into the main window menu).
If you're after a full-fledged doc/view architecture, I guess you're heading a lot of work for it to function based on a plugin system.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Okay, here is the idea I came up with. Since we do not want to have to recompile the app everytime we add support for a new hardware product we produce, we have this "shell" app that simply scans for plugins/ActiveX controls in a certain directory (or you select them from the app . . .) And the app will then make the features available in the plugin available to the user (ie if it is a communications plugin for the serial port, a menu would be appended to the top-level menu called "Communications" with options like "Configure", "Connect", and "Disconnect"). The whole idea is that we would only have to redistribute the application if we found a bug in it somewhere (making it easy to upgrade by simple adding new features via plugins that can be made available). The other benefit is that the application itself is worthless without one or more plugins (since it only functions via plugins), which would also make it very easy to give out demo versions (of some of the plugins) and give them the full-fledged application to evaluate.
Thanks again
Zac
|
|
|
|
|
for my stuff, i just defined a COM interface and told plugin writers "implement this interface, name it thusly and put your plugin DLL in this folder". then, to see which plugins are available, i just scan the folder and attempt to Create an instance of each DLL. it works well. people can write plugins for my stuff using any language that can create an IDispatch interface (this includes the biggies, VB and VC).
it is somewhat ugly to have to scan a folder, but it was the easest way to go. there is some COM interface that you can implement that tells the system "yes, i implement this other interface". that would have allowed me to use yet another interface to query the system to see which components implemented my plugin interface,
but there were difficulties getting VB to implement a non-IDispatch interface. so, i went with the scan-the-folder option.
-c
Conscience is what hurts when everything else feels good.
Smaller Animals Software, Inc.
|
|
|
|
|
Am I going crazy? I decided I want to do some DX work on my XP box. I need the DX 8.1 SDK, but I prefer the CD-ROMS over the download. I have up until 8 on CD-ROM, but can't find a link for the world of it to order 8.1. Anyone out there have a link?
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
How to used "Multiple Display Monitors" and "virtual screen" with the c & c++ & sdk, Who can tell me this and give me some source.
|
|
|
|
|
I've never done it myself...but have read about it a few times and I think it's pretty simple.
GetSystemMetrics()
Using
SM_XVIRTUALSCREEN
SM_YVIRTUALSCREEN
SM_CXVIRTUALSCREEN
SM_CYVIRTUALSCREEN
SM_CMONITORS
Use the 5 following API functions:
EnumDisplayMonitors()
GetMonitorInfo()
MonitorFormPoint()
MonitorFromRect()
MonitorFromWindow()
Psuedo-code:
int monView[9][2];
int nMonitors = 0;
BOOL CALLBACK MonInfo(HMONITOR hMon, HDC hdc, LPRECT rect, LPARAM extra){
MONITORINFOEX mi;
mi.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hMon, &mi);
monView[nMonitors][0] = mi.rcMonitor.left;
monView[nMonitors][1] = mi.rcMonitor.top;
nMonitors++;
return TRUE;
}
OnCreate(){
m_pxTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
m_pxLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
m_pxRight = GetSystemMetrics(SM_CXVIRTUALSCREEN);
m_pxBottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
::EnumDisplayMonitors(NULL, NULL, MonInfo, 0);
}
Obviously this is not a complete example of source, but will get you started. Read up on MSDN on the preceeding functions and you should figure it out from here.
Cheers!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
This is frightening:
c:\Development\Projects\phantom\phantom-edlib-win\PhantomExplorer.cpp(110): warning C4996: 'CWinApp::Enable3dControlsStatic' was declared deprecated
Does this mean MS is soon going to force us to link dynamically to their libraries?
This is the thing I hate about that company: forcing is to walk in their footsteps, regardless of our needs.
|
|
|
|
|
Seemingly, it only means that 3D controls are provided by default (relief sigh).
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I need to calculate the length in pixels of a printed text (on the screen).
It's painted using a true-type font, so i would like to know if there is a simple function(font, text) to give me just what i need.
rechi
|
|
|
|
|
No, but it's easy to write one using DrawText() with the DT_CALCRECT flag.
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
|
|
Use GetTextExtent or one of its variants to get the width. However, it is usually best to use GetTextMetrics to get the height. TEXTMETRIC.tmHeight represents the absolute height of the tallest character for a given font. I'm fairly certain that GetTextExtent will only give you the height of whatever characters are in the string and that may vary according to the characters.
"There's a slew of slip 'twixt cup and lip"
|
|
|
|
|
Need some help, please. This is my first shot at using the MFC wizard.
I choose MFC Appwizard (exe).
Single doc
No doc/view support
No Database
ActiveX
MFC Standard
Static Link Library
Finish
Compile and Link Good.
Go to View
Class Wizard
Add Class
From Type Lib
AWREM32.TBL from Symantec (PCAnywhere)
Compile and link good
Add function to my Application .CPP
Compile
C2065 Undeclared Identifier.
Can anyone please tell me what I am doing wrong?
Thanks.
|
|
|
|
|
Check for typos! What does the function look like? Are you declaring your variables (they are case-sensitive)? For instance...
int myFunction()
{
int x=0;
return y;
}
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Hi Jeremy,
The TLB adds a .H and a .CPP file to my project. This is a class
that was added. I have checked these for spelling and declarations.
All seem to be fine. Is there anything special I have to do to get a
class to work? I can add an extern for the function I added to my
base code and can get thru the compile, but the link fails. I was
under the impression that when files are added to your project, they
are accessible by the base program. It appears this is not
happening. I have attached the TLB I am trying to use. Maybe you
can tell me what is wrong.
Thanks for your help.
|
|
|
|
|
Did you #include the header file in the other CPP file you wanted to use the class in?
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
I tried that. No Change. The include is actually in the AWREM32.CPP file.
|
|
|
|
|
Barry R. Martin wrote:
I tried that. No Change. The include is actually in the AWREM32.CPP file.
You'll need to include it in your own CPP file too. Can you post some sample code for us to look at?
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Here is the testa app and the awrem32 files. I have played with this and tried to include the various code in my testa app, but to no avail. I am running MS Visual C++ Rel 6. If you have this environment, just follow the original steps I took and include the TLB I sent you. It should fail the same way. I am really confused and I thank you for taking the time to look at my problem.
// testa.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "testa.h"
#include "awrem32.h" // <---- ADDED AS PER YOUR SUGGESTION
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTestaApp
BEGIN_MESSAGE_MAP(CTestaApp, CWinApp)
//{{AFX_MSG_MAP(CTestaApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestaApp construction
CTestaApp::CTestaApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
GetError(); // <---- THIS IS THE FUNCTION I AM TYING TO USE!
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CTestaApp object
CTestaApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CTestaApp initialization
BOOL CTestaApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
// To create the main window, this code creates a new frame window
// object and then sets it as the application's main window object.
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
// create and load the frame with its resources
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);
// The one and only window has been initialized, so show and update it.
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CTestaApp message handlers
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CTestaApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CTestaApp message handlers
/ Machine generated IDispatch wrapper class(es) created with ClassWizard
#include "stdafx.h"
#include "awrem32.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// IAWREM32 properties
/////////////////////////////////////////////////////////////////////////////
// IAWREM32 operations
BOOL IAWREM32::FileXferFromHost(LPCTSTR HostFile, LPCTSTR RemoteFile)
{
BOOL result;
static BYTE parms[] =
VTS_BSTR VTS_BSTR;
InvokeHelper(0x1, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms,
HostFile, RemoteFile);
return result;
}
BOOL IAWREM32::awConnect(LPCTSTR FileName)
{
BOOL result;
static BYTE parms[] =
VTS_BSTR;
InvokeHelper(0x2, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms,
FileName);
return result;
}
BOOL IAWREM32::FileXferToHost(LPCTSTR HostFile, LPCTSTR RemoteFile)
{
BOOL result;
static BYTE parms[] =
VTS_BSTR VTS_BSTR;
InvokeHelper(0x3, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms,
HostFile, RemoteFile);
return result;
}
CString IAWREM32::GetError()
{
CString result;
InvokeHelper(0x4, DISPATCH_METHOD, VT_BSTR, (void*)&result, NULL);
return result;
}
BOOL IAWREM32::ExecuteHostFile(LPCTSTR FileName)
{
BOOL result;
static BYTE parms[] =
VTS_BSTR;
InvokeHelper(0x5, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms,
FileName);
return result;
}
BOOL IAWREM32::awDisconnect()
{
BOOL result;
InvokeHelper(0x6, DISPATCH_METHOD, VT_BOOL, (void*)&result, NULL);
return result;
}
short IAWREM32::ConnectionStatus()
{
short result;
InvokeHelper(0x7, DISPATCH_METHOD, VT_I2, (void*)&result, NULL);
return result;
}
long IAWREM32::CreateFolderOnHost(LPCTSTR FolderName)
{
long result;
static BYTE parms[] =
VTS_BSTR;
InvokeHelper(0x8, DISPATCH_METHOD, VT_I4, (void*)&result, parms,
FolderName);
return result;
}
// Machine generated IDispatch wrapper class(es) created with ClassWizard
/////////////////////////////////////////////////////////////////////////////
// IAWREM32 wrapper class
class IAWREM32 : public COleDispatchDriver
{
public:
IAWREM32() {} // Calls COleDispatchDriver default constructor
IAWREM32(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
IAWREM32(const IAWREM32& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}
// Attributes
public:
// Operations
public:
BOOL FileXferFromHost(LPCTSTR HostFile, LPCTSTR RemoteFile);
BOOL awConnect(LPCTSTR FileName);
BOOL FileXferToHost(LPCTSTR HostFile, LPCTSTR RemoteFile);
CString GetError();
BOOL ExecuteHostFile(LPCTSTR FileName);
BOOL awDisconnect();
short ConnectionStatus();
long CreateFolderOnHost(LPCTSTR FolderName);
};
|
|
|
|
|
Ok, I'll check my email when I get home. Right now I'm at work and behind a proxy server.
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Here's the deal. You need to create an instance of the class. The instanced is called an object, hence Object-Oriented Programming (OOP). Try this instead...
IAWREM32 pcAny;
pcAny.GetError(); The class is IAWREM32 and you declare a variable (identifier) of that class, which in turn creates an instance of the class (an object). Then you can use dot notation to access public members of that class.
FYI, a function inside a class that performs some action is generally referred to as a method.
Good luck!
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Hi Jeremy,
I included the code you suggested in my base app. This was the result.
compiling...
testa.cpp
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MyProjects\testa\testa.cpp(15) : error C2146: syntax error : missing ';' before identifier 'pcAny'
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MyProjects\testa\testa.cpp(15) : error C2501: 'IAREM32' : missing storage-class or type specifiers
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MyProjects\testa\testa.cpp(15) : fatal error C1004: unexpected end of file found
// testa.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "testa.h"
#include "awrem32.h" // <---- ADDED AS PER YOUR SUGGESTION
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IAREM32 pcAny; // <----- NEW CODE
/////////////////////////////////////////////////////////////////////////////
// CTestaApp
BEGIN_MESSAGE_MAP(CTestaApp, CWinApp)
//{{AFX_MSG_MAP(CTestaApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestaApp construction
CTestaApp::CTestaApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
pcAny.GetError(); // <---- THIS IS THE FUNCTION I AM TRYING TO USE!
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CTestaApp object
etc......
|
|
|
|
|
It's a typo.
IAREM32 pcAny; Should be...
IAWREM32 pcAny; Good luck!
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Hi Jeremy,
Got it to go. One more question, if I may. I have inserted code to display a statement with a printf at the construcion function, as is indicated by the base code. I pop the window, but don't see the printf output. I have written alot of "C" code from scratch, but in a DOS environment, so I am not used to the base codes as is created in the windows environment. Am I placing my code in the wrong place or am I missing something else. Your help is always appreciated.
// testa.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "testa.h"
#include "awrem32.h"
#include "io.h"
#include "conio.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IAWREM32 pcAny;
/////////////////////////////////////////////////////////////////////////////
// CTestaApp
BEGIN_MESSAGE_MAP(CTestaApp, CWinApp)
//{{AFX_MSG_MAP(CTestaApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestaApp construction
CTestaApp::CTestaApp() // <---- THIS IS WHERE I THOUGHT THE CODE SHOULD GO
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
CString rc;
rc = pcAny.GetError();
printf( "Return Code = %s/n", rc );
getch();
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CTestaApp object
CTestaApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CTestaApp initialization
BOOL CTestaApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
// To create the main window, this code creates a new frame window
// object and then sets it as the application's main window object.
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
// create and load the frame with its resources
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);
// The one and only window has been initialized, so show and update it.
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CTestaApp message handlers
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CTestaApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CTestaApp message handlers
|
|
|
|
|