I'm currently working on a project using Borland C++, I have two Forms so far but each one in an independent Project, I wish to join these two project into one project so I can switch between the Forms.
I want to have only one executable file (for security purposes), I tried reading some pdfs about borland c++, also tried googling it, but no luck.
if there's a way to do so, I wish you could guide me or give me some hints.
Note: I'm using Borland C++ Builder 6, under Windows 8.1.
I am used to BDS2006 so for newer IDE/Compilers it can be different
1.form copy
has .h,.cpp,*.dfm files
copy them to target project directory
2.open target project in IDE
3.add forms to project
find add to project in IDE main menu (I think it is in Project tag)
then select *.dfm files of your new forms click add or OK ...
4.Open target project source code (*.cpp)
should look like this:
//$$---- EXE CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
//*** here you have line for each form type and its name in forms menu
USEFORM("win_view.cpp", win_view);
USEFORM("win_main.cpp", win_main);
USEFORM("win_editor\win_editor_setup.cpp", win_EditorSetup);
USEFORM("win_editor\win_editor.cpp", win_editor);
USEFORM("win_editor\win_editor_find.cpp", win_EditorFind);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
//*** here create form for each static form you want
//*** dynamic windows (created in runtime are not here !!!
Application->CreateForm(__classid(Twin_main), &win_main);
//*** here load cross references to forms if needed
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
5.dynamic forms
add #include of *.h for all dynamic/used inside form files to main form cpp file
this makes them accessible from main form
now you can crete / destroy windows
should look like this:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "win_main.h"
//*** add the dynamic/used forms *.h files
#include "win_view.h"
#include "win_editor\win_editor.h"
//---------------------------------------------------------------------------
//*** add pointer to dynamic forms
Twin_view *win_view=NULL;
//---------------------------------------------------------------------------
void __fastcall Twin_main::some_event(...)
{
win_view=new Twin_view(win_main);
if (win_view)
{
win_view->OnResize(win_view);
win_view->_can_close=false;
}
}
//---------------------------------------------------------------------------
void __fastcall Twin_main::FormDestroy(TObject *Sender)
{
//*** destroy form before exiting also can call ->Close() and wait few [ms] before
if (win_view) { delete win_view; win_view=NULL; }
}
//-------------------------------------------------------------------
you can also move the form pointers to owner form class to make it more objective c++ like
and allow to make multiple originaly main forms in future (in another project later)
6.static used forms
just include *.cpp file instead of *.h
the pointer to these forms are directly in *.cpp files (at the start)
[notes]
if your forms have some global variables
then you can not use more then 1 form of that type
also the global variable names have to be different between used forms
do not change namespace for them it will make VCL crazy
Related
I have a Windows Form on a new C++ project, a Button1, and inside the Button1 code am using some trig functions. I also have #include <cmath> in the resource.h file next to Form1.h file. (Below is the contents of resource.h):
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc
#include <cmath>
Why is the code not seeing the trig function?
The Button1 code is as follows:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
double x[1000];
double y[1000];
double hifac;
double px[1000];
double py[1000];
int nout, jmax;
double prob;
int i,period;
period=300;
for (i=0; i<1000;i++){
x[i]=i;
y[i]=sin(2 * 3.14 * i / period);
}
}
Just put appropriate code in its appropriate place. That #include does not belong in resource.h, that header file should be reserved strictly for resource identifier definitions for unmanaged resources. Just about anywhere else is appropriate, obvious choices are source file where this code appears and the stdafx.h precompiled header file.
And use the appropriate math function. It is std::sin(), the missing namespace name is surely why you get the compiler complaint. But calling that function from managed code is inefficient, extra work is needed to run native code from managed code. It isn't much extra work but it is unnecessary work. Use Math::Sin() instead.
I am going to design a program using WinDivert to manipulate the network traffic.
The language I use is C++ and the program is designed under Visual Studio 2008.
Firstly I create a project in visual C++ CLR (Windows Forms Application) so I can implement the UI simply.
For importing the WinDirvert Library, I have done the following setting in project properties:
Configuaration Properties: General
Common Language Runtime support: Common Language Runtime Support(/ctr)
Configuaration Properties: Linker
Additional Dependencies: link of WinDivert.lib
Module Definition File: link of windivert.def
Within the project I have created, I also added the windivert.h in the header files.
Also, windivert.h is included in the main entry point of my project (ProjectG.cpp):
#include "stdafx.h"
#include "Form1.h"
#pragma managed(push, off)
#include "windivert.h"
#pragma managed(pop)
using namespace ProjectG;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
HANDLE handle;
unsigned char packet[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
handle = WinDivertOpen("udp", WINDIVERT_LAYER_NETWORK, 0,
WINDIVERT_FLAG_DROP);
if (handle == INVALID_HANDLE_VALUE)
{
Application::Exit();
}
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
MessageBox::Show("Fail");
continue;
}
}
return 0;
}
Finally, I put the {WinDivert.dll, windivert.h, WinDivert.lib, WinDivert32.sys} under the project directory.
However, the following error is shown:
fatal error LNK1306: DLL entry point "int __clrcall main(cli::array<class
System::String ^ >^)" (?main##$$HYMHP$01AP$AAVString#System###Z) cannot be managed;
compile to native ProjectG.obj ProjectG
Additional: (a warning)
warning LNK4070: /OUT:WinDivert.dll directive in .EXP differs from output filename
'C:\Users\David\Desktop\css\ProjectG\Debug\ProjectG.exe'; ignoring directive
ProjectG.exp ProjectG
Question:
How can I resolve this situation?
a) your main source is .cpp, so you can delete [STAThreadAttribute] and change
int main(array<System::String ^> ^args) to int _tmain(int argc, _TCHAR* argv[])
b) exclude windivert.def from linker Module Definition File, this only when you are creating a DLL
c) the DLL/SYS files would need to be copied to the Debug and Release folders
I have created a GUI using tcl. I want to make some of the core functionalities of the tcl code available to be used by any program which supports dll. For that i have taken a very simple tcl code example, which adds two integer numbers and i have written a c wrapper function to use this functionality. This is working for me. Now how can i create a dll for these two c and tcl files, so that any program can use this addition functionality by simply loading the dll.
Here is my simple tcl code :
/* Filename : simple_addition.tcl */
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is my c wrapper function which uses the above tcl addition functionality :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
This c wrapper is working fine for me and gives correct results.
Now I want to create a dll file, so that if i include that dll to any program that supports dll, it should be able to use this addition functionality of the above tcl code. Can anybody please tell me the way i can do it. Please help me. I am new to this dll concept.
In order to create the .dll you'll have to use something like Visual Studio and C or C++ to create the .dll (there are lots of other tools out there that can create .dll files but VS is easy to get hold of and to use.) So in VS create a new project, this needs to be a C++ WIN32 project. Select the DLL application type and the Export Symbols additional option.
VS will create a basic .dll that you can then amend to do what you want. I short I'd look at putting the creating/destruction of the intrepter into the dllmain:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
Tcl_DeleteInterp(interp);
break;
}
}
return TRUE;
}
and then create functions exported by the .dll that make use of the interpreter. If you aren't familiar with the concept of shared libaries then I'd suggest spending a little time reading up on them, try here and here for some background reading.
I'm trying to make a solution in Visual Studio that consists of a VC++ DLL (C++/CLI) and a VB.Net application. To figure this out, I created a VC++ Class Library project, with the following code (I removed all the junk the wizard creates):
mathfuncs.cpp:
#include "MathFuncs.h"
namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b)
{
return a + b;
}
}
mathfuncs.h:
using namespace System;
namespace MathFuncs
{
public ref class MyMathFuncs
{
public:
static double Add(double a, double b);
};
}
This compiles quite happily. I can then add a VC++ console project to the solution, add a reference to the original project for this new project, and call it as follows:
test.cpp:
using namespace System;
int main(array<System::String ^> ^args)
{
double a = 7.4;
int b = 99;
Console::WriteLine("a + b = {0}",
MathFuncs::MyMathFuncs::Add(a, b));
return 0;
}
This works just fine, and will build to test.exe and mathsfuncs.dll.
However, I want to use a VB.Net project to call the DLL. To do this, I add a VB.Net project to the solution, make it the startup project, and add a reference to the original project. Then, I attempt to use it as follows:
MsgBox(MathFuncs.MyMathFuncs.Add(1, 2))
However, when I run this code, it gives me an error:
Could not load file or assembly 'MathFuncsAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Do I need to expose the method somehow?
I'm using Visual Studio 2008 Professional.
I get that sometimes when the project platform is not set correctly.
Go to your project settings > Compile > Advanced Compile options and select target CPU x86.
Initially, I followed the structure of http://qt-project.org/wiki/How_to_use_OpenGL_Core_Profile_with_Qt. I created a vanilla Visual Studio 2010 Qt application project, clicked on the .ui file to start Qt Designer, inserted a QWidget and promoted it to myglwidget. I then created a myglwidget subclass of QGLWidget.
That worked fine, and I got my red triangle.
The issue is that myglwidget doesn't get any of the resize events when the main window is resized, even if I set the widget size properties to "expanding."
And when I restructure my app constructor to call setCentralWidget(&myglwidget_) the code compiles and runs but no OpenGL window appears.
I'm not seeing how to resize my widget to match the main window size. I'm also not understanding why the setCentralWidget approach didn't work.
I believe I know how to solve the problem by writing explicit Qt code, but that defeats the purpose of my trying to build an OpenGL app in Qt using Qt Designer.
The following code for the application "baz6" fixes the problem. The code I inserted in the wizard-generated code is flagged with //***
baz6.h:
#ifndef BAZ6_H
#define BAZ6_H
#include <QtGui/QMainWindow>
#include "ui_baz6.h"
#include "myglwidget.h" //***
#include <QResizeEvent>
class baz6 : public QMainWindow
{
Q_OBJECT
public:
baz6(QWidget *parent = 0, Qt::WFlags flags = 0);
~baz6();
private:
Ui::baz6Class ui;
myGLWidget *myglwidget_; //***
};
#endif // BAZ6_H
baz6.c:
#include "baz6.h"
#include "myglwidget.h"
baz6::baz6(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
myglwidget_ = new myGLWidget(); //***
setCentralWidget(myglwidget_); //***
}
baz6::~baz6()
{
}
Previously, I had not explicitly constructed the myGLWidget.