Powerbasic Museum 2020-B

IT-Consultant: Patrice Terrier => C++ programming (SDK style) => Topic started by: Patrice Terrier on July 30, 2010, 10:01:29 AM

Title: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 10:01:29 AM
I started this new thread to see how close i could convert some of my PB's code into C++ using the core SDK syntax i am familiar with.

...
Title: Bare bone Win32 SDK window template
Post by: Patrice Terrier on July 30, 2010, 12:13:56 PM
This is a bare bone Win32 SDK window template:

// HelloWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variable
HINSTANCE g_hInst; // Current instance

// Declaration of the functions being used in this module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int WINAPI wWinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR lpCmdLine,
                    int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // Declaration of local variables
    MSG msg;
    int nRet = 0;
    int IsInitialized = 0;
    WNDCLASSEX wcx;
    TCHAR szWindowClass[] = _T("win32app");
    TCHAR szTitle[] = _T("Win32 Guided Tour Application");

    // Register the main window class
    wcx.cbSize = sizeof(WNDCLASSEX);
    IsInitialized = GetClassInfoEx(hInstance, szWindowClass, &wcx);
    if (!IsInitialized)
    {
        wcx.style         = CS_HREDRAW | CS_VREDRAW;
        wcx.lpfnWndProc   = WndProc;
        wcx.cbClsExtra    = 0;
        wcx.cbWndExtra    = 0;
        wcx.hInstance     = hInstance;
        wcx.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcx.lpszMenuName  = NULL;
        wcx.lpszClassName = szWindowClass;
        wcx.hIconSm       = LoadIcon(wcx.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        if (RegisterClassEx(&wcx))
        {
           IsInitialized = -1;
        }
     }

     if (IsInitialized)
     {
        g_hInst = hInstance; // Stocke le handle d'instance dans la variable globale
   
        HWND hWnd = CreateWindowEx(
                    0,                              // Optional window styles.
                    szWindowClass,                  // Window class
                    szTitle,                        // Window text
                    WS_OVERLAPPEDWINDOW,            // Window style
   
                    // Size and position
                    CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
   
                    NULL,       // Parent window   
                    NULL,       // Menu
                    hInstance,  // Instance handle
                    NULL        // Additional application data
                    );
   
        if (hWnd)
        {
   
           ShowWindow(hWnd, nCmdShow);
           UpdateWindow(hWnd);
   
           // Main message loop
           while (GetMessage(&msg, NULL, 0, 0))
           {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
           }
           nRet = msg.wParam;
        }
     }
   
     return nRet;
}

// Main winproc
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (uMsg)
    {
    case WM_COMMAND:
         wmId    = LOWORD(wParam);
         wmEvent = HIWORD(wParam);
         // Process menu command
         //switch (wmId)
         //{
         //case IDM_ABOUT:
         //     DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
         //     break;
         //case IDM_EXIT:
         //     DestroyWindow(hWnd);
         //     break;
         //}
         return 0;
    case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
         // TODO: process here the WM_PAINT message...
         EndPaint(hWnd, &ps);
         return 0;
    case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
    }
   
    return DefWindowProc(hWnd, uMsg, wParam, lParam);


//// The about dialog function
//INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
//{
//    UNREFERENCED_PARAMETER(lParam);
//    switch (message)
//    {
//    case WM_INITDIALOG:
//         return (INT_PTR)TRUE;
//
//    case WM_COMMAND:
//         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
//         {
//            EndDialog(hDlg, LOWORD(wParam));
//            return (INT_PTR)TRUE;
//         }
//         break;
//    }
//    return (INT_PTR)FALSE;
//}



Note: This bare bone window is compatible 32/64-bit, because UINT or INT are being used only when it it is the same in 32/64-bit.
Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 30, 2010, 01:23:55 PM
Looks good Patrice,

and also compatible 32/64bit!

Here my procedures for an OpenGl Window:
void Shutdown()
{
if (fullscreen)
{
ChangeDisplaySettings(NULL,0);
ShowCursor(TRUE);
}

wglMakeCurrent(NULL,NULL);

wglDeleteContext(RC);
RC=NULL;

ReleaseDC(hWnd,DC);
DC=NULL;

DestroyWindow(hWnd);
hWnd=NULL;

UnregisterClass(ClassName, hInstance);
hInstance=NULL;
}


int LoadTexture( unsigned &Texturehandle , char * texturefilename)
{

pngInfo info;

glGenTextures(1, &Texturehandle);
glBindTexture(GL_TEXTURE_2D, Texturehandle);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

if (pngLoad(texturefilename, PNG_BUILDMIPMAPS, PNG_ALPHA, &info)) {
   
return TRUE;

}else{

return FALSE;

}

}


int InitTextures()
{
        // Code
return TRUE;

}

int InitGL()
{

glEnable(GL_TEXTURE_2D);

if (!InitTextures())
return FALSE;

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA,GL_DST_ALPHA);

//glDisable(GL_DEPTH_TEST);
//glClearDepth(1.0);
//glDepthFunc(GL_LESS);
//glEnable(GL_DEPTH_TEST);

glShadeModel(GL_SMOOTH);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

return TRUE;
}


// ReSize
void ReSize(int width, int height)
{
glViewport(0,0,width,height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective (45,(double)width/(double)height,1,100000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
}

case WM_CLOSE:
{
b_actif=FALSE;
return 0;
}

case WM_KEYDOWN:
{
// Code
return 0;
}

case WM_KEYUP:
{
// Code
return 0;
}

case WM_SIZE:
{
ReSize(LOWORD(lParam),HIWORD(lParam));
return 0;
}
}

return DefWindowProc(hWnd,uMsg,wParam,lParam);
}


// CreateGLWindow
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
fullscreen=fullscreenflag;

hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;

RegisterClass(&wc);

if (fullscreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN);
}

if (fullscreen)
{
dwExStyle=WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
}

ShowCursor(TRUE);

AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);

hWnd=CreateWindowEx(dwExStyle, ClassName, title, dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top,
NULL, NULL, hInstance, NULL);

static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};

DC=GetDC(hWnd);

SetPixelFormat(DC,ChoosePixelFormat(DC,&pfd),&pfd);

RC=wglCreateContext(DC);

wglMakeCurrent(DC,RC);

ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);

return TRUE;
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;

// on crée la fenêtre
if(!CreateGLWindow(APPName,1024,768,32,fullscreen))
{
MessageBox (HWND_DESKTOP, "Impossible de créer la fenêtre principale", "Erreur", MB_OK | MB_ICONEXCLAMATION);

// on quitte le programme
return -1;

}


// on initialise le programme
if(!InitGL())
{
MessageBox (HWND_DESKTOP, "Impossible d'initialiser le programme", "Erreur", MB_OK | MB_ICONEXCLAMATION);

// on quitte le programme
return -1;

}

        // Rezize routine
ReSize(1024, 768);

b_actif = TRUE;

while(b_actif)
{

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{

if (msg.message==WM_QUIT)
{

b_actif=FALSE;
}
else
{
// non, on passe le message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{

RePaint();

}
}


Shutdown();

// on quitte le programme
return (msg.wParam);
}


Maybe it`s also usedull!?

..  ;)
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 02:47:05 PM
Jürgen,

Indeed my question was:
Quotehow to create the C++ header file for my GDImage.inc

Here is an example of what i would like to turn into a C++ header:

'//5.06
' Assign a new texture to an existing OpenGL "Named texture".
  DECLARE FUNCTION ZI_UpdateNamedGLTextureFromFileEx LIB "GDIMAGE.DLL" ALIAS "ZI_UpdateNamedGLTextureFromFileEx" ( _
  zFullName AS ASCIIZ, _        ' Full qualified path name.
  BYVAL NamedTexture AS LONG, _ ' An existing OpenGL NamedTexture
  BYVAL SquareMode AS LONG _    ' The square mode to use
  ) AS LONG
' Return:
' An OpenGL error code in case of Error.


I know how i could do it using "LoadDll" and "LoadLibrary" (explicit linking)
but i don't know the syntax to use to make implicit linking like in PowerBASIC.
Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 30, 2010, 04:46:19 PM
 ::)

Sorry Patrice,
for having misunderstood your Question:

I was on another Planet and on the way to thinking about that`s needed to
use more and more C++/C# next comming times.
It makes not really Sense to Compile for WinVista and Win7 in 32bit Code and Compiler, because after last updares for InternetExplorer8 and OperatingSystems some functions doesn´t work.
I use an add on Menu, that`s a little Program that`s starts with IExplorer. I wrote it in PB 32bit.
The Menü appears but some calls on Functions from Menu to IExplorer8 are in 64bit wide on new Datatype`s or something like else.
Instead to lost a lot time by figure out what it is, i  translatet the PB code and wrote a small part newi in C++.  After short time debugging and compiled with Microsoft Visual Basic 2010...
The Menu appears faster and also a bit smoother or better rendered on open and closing time.
But i changed no Datatypes off my MenuCode to 64bit. I thought just to try it and all works very well.

I hope a PB 64bit Compiler is comming soon!

QuoteI know how i could do it using "LoadDll" and "LoadLibrary" (explicit linking)
but i don't know the syntax to use to make implicit linking like in PowerBASIC.

Of course Patrice and i know this very well.. Instead of understanding your Question i wonder!!Also about your first steps..


??? ???

:)

Sorry once again,

...
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 05:09:21 PM
C++ gurus, my question is still there.

What is the syntax to use to call from a C++ Win32 application, a function or subroutine exported from a PowerBASIC 32-bit DLL?

:o
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 06:02:59 PM
Here is an example of explicit DLL linking, using LoadLibrary and GetProcAdress to call my zTrace utility.

void zTrace(char szMsg[])
{
   typedef int (__stdcall *ZTRACE) (char*);
   ZTRACE hPROC;

   HMODULE hDLL = LoadLibrary(_T("zTrace.dll"));
   if (hDLL)
   {
      hPROC = (ZTRACE) GetProcAddress(hDLL, "zTrace");
      if (hPROC)
      {
          int nRet = hPROC(szMsg);
      }
      else
      {
          FreeLibrary(hDLL);
      }
   }
}


Now how to use it with implicit linking?

...
Title: Re: My first steps with C++
Post by: José Roca on July 30, 2010, 06:44:02 PM
Quote
To implicitly link to a DLL, executables must obtain the following from the provider of the DLL:

    * A header file (.h file) containing the declarations of the exported functions and/or C++ classes. The classes, functions, and data should all have __declspec(dllimport), for more information, see dllexport, dllimport.

    * An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.)

    * The actual DLL (.dll file).

http://msdn.microsoft.com/en-us/library/d14wsce5%28VS.90%29.aspx

Guess that the C++ package will include a utility to make an import .lib file from the .dll.
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 07:07:14 PM
José,

QuoteTo implicitly link to a DLL, executables must obtain the following from the provider of the DLL:
   * A header file (.h file) containing the declarations of the exported functions and/or C++ classes. The classes, functions, and data should all have __declspec(dllimport), for more information, see dllexport, dllimport.
   * An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.)
   * The actual DLL (.dll file).

I have read the help file, and i see this already...
But the problem is how to create the LIB file.  ;)

Hello Mike?

Added: Looks like the solution would be to use LIB.exe

Title: Re: My first steps with C++
Post by: James C. Fuller on July 30, 2010, 07:10:00 PM
And now you have to create four libraries instead of just one with PB.
ansi 32 bit
ansi 64 bit
unicode 32 bit
unocode 64 bit

James
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 07:15:13 PM
So far ANSI 32-bit would be fine  ;D

...

Title: Re: My first steps with C++
Post by: James C. Fuller on July 30, 2010, 07:16:25 PM
I'm not sure if this will help??

http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855/

James
Title: Re: My first steps with C++
Post by: Patrice Terrier on July 30, 2010, 07:41:28 PM
James,

Thank you.

Here is another link:
http://support.microsoft.com/kb/131313/en-us

I never thought that it was so hard to use an external DLL written with another language with C++

in C# it is almost as easy as in PB, example:
       [DllImport(GDIMAGE)]  // Retrieve the GDImage mouse captured X,Y location.
       public static extern void ZD_GetObjectXYcapture(
       int ObjID,          // The unique sprite object identifier.
       out int x,          // The X coordinate
       out int y           // The Y coordinate
       );

Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 30, 2010, 08:01:54 PM
I wanted to give you a sign as long PB is compiling in 32bit, translate the DLL to c++ is the best.

Or go to:
http://msdn.microsoft.com/en-us/library/7ykb2k5f(v=VS.90).aspx

Here is a description with code examples
http://www.codeproject.com/KB/DLL/loadingdll.aspx (http://www.codeproject.com/KB/DLL/loadingdll.aspx)
Title: Re: My first steps with C++
Post by: James C. Fuller on July 30, 2010, 08:17:18 PM
Patrice,
  Even if you are committed to Visual c++   It might help to play around with Bcx3264. Write the code in Bcx Then examine the c++ code created. I know it has helped me quite bit with my c++ education.

James
Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 30, 2010, 08:54:04 PM
It`s good to know this:

From Microsoft to Development of Visual C++:

-----------------------------------------------------------------------
long long n = 9223372036854775807LL; // Works fine.
printf("n: %lld\n", n);             // Output n:
// 9223372036854775807

// (correct)
   printf("n: %+lld\n", n);     // Output n:
// (wrong)
    printf("n: %5lld\n", n);  // Output wrong

------------------------------------------------------------------------
Thanks for the report. We need more information to process this bug

- what compiler options and CPU are you compiling for
- what was the actual output you saw from this program
- what output did you expect to see?

Please reactivate this bug with the extra information.

Thanks,

Martyn Lovell
Development Lead
Visual C++ Libraries

Most of the articles describe how to do it in Visual Basic, but I think it`s
near to finding how to do it accurate in Visual C++.
,,,
Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 30, 2010, 09:16:58 PM
Quote
QuoteGuess that the C++ package will include a utility to make an import .lib file from the .dll.

I wrote about it also in  OpenGl thread..

The question was,

is it allowed to translate OpenGl.dll to PowerBasic?
Most of other Compiler inluding yet Tools for translation. (as as is) 1 to 1..
...
Title: Re: My first steps with C++
Post by: Jürgen Huhn on July 31, 2010, 08:18:15 AM
Good moorning to all!

I have tried the imnport procedures of Visual C++ 2010.
And the locations of Menu `s are on other Positions in Visual C++ 2010 and even enhanced for importing a DLL.
The procedures in my older licenced  Microsoft Visual C++ 6.0, are working on the main principle  equal as in Visual C++ 2010, but i didn`t used  until tofay the .dll import in Visual C++ 2010

I also want to explain my confusion about questions i had yesterday, it could be consisting additional knowlege:

Question from Patrice was;

QuoteJürgen,

Indeed my question was:

Quote
how to create the C++ header file for my GDImage.inc

Here is an example of what i would like to turn into a C++ header:


... example ..
 

Here is an example of explicit DLL linking, using LoadLibrary and GetProcAdress to call my zTrace utility.


... example ...



Until Jose`s Statements about the Tools to create the translation for the import procedure,


i really was in the good faith that you well know how to implicitly linking a DLL in C++ with the import Tools there
and you needed the syntax to create your import Library manually, not with the linker Tool.)

Because of your examples after your Question and the Fact that i know you as a very good Programmer with a large professional Knowlege.

----------------------------------------------------------------------------------------

I know how i could do it using "LoadDll" and "LoadLibrary" (explicit linking)              ' <-- many times i read in your Codes how you performt "LoadLibrary" in PB.
but i don't know the syntax to use to make implicit linking like in PowerBASIC.            ' <-- My brain was cooking about how to do that with your GDI_Image.dll
                                                                                       

Of course Patrice and i know this very well.. Instead of understanding your Question i wonder!!Also about your first steps..
------------------------------------------------------------------------------------

implicit linking like in PowerBASIC says to me "manually translation without any Tool to get a translation for an import to PB". 


I was wondwering and i don`t know any about the Routines that you wanted to import from your .dll ( for mwe apparently to follow the manualy Way on your examples..)

For sure that is also possible, even to have other Situations , or that we must link part`s of .dll Code manually that`s depending on the used Data Types used
on import functions that use calling conventions other than in C/C++.

I`m glad that we have Jose who filled once again at the right Point of Disscussion the Gap with the right Statement.

Also thank`s to all other`s for they given Statement`s to find that what was needeed.

Nwxt i`ll try to to play around with Bcx3264.

My intension was to help and i`ve learned a lot on this Disscussion.

...    :)

Title: Re: My first steps with C++
Post by: Patrice Terrier on July 31, 2010, 09:50:56 AM
Here is another question.

What is the best (and most concise) way to translate this small piece of PB's code to C++:
QuoteMixedString$ = "Window handle =" + STR$(hWnd&)

:)
Title: Re: My first steps with C++
Post by: James C. Fuller on July 31, 2010, 01:23:46 PM
Quote from: Patrice Terrier on July 31, 2010, 09:50:56 AM
Here is another question.

What is the best (and most concise) way to translate this small piece of PB's code to C++:
QuoteMixedString$ = "Window handle =" + STR$(hWnd&)

:)

Patrice,
  I am a real c++ novice but I am in education mode now and was looking for something similar.
I am primarily using wxWidgets which has it's own string handling but it's similar to the STL std::string
This is what I came up with. I am sure there is better....
Here is a reference to std::strings : http://www.cplusplus.com/reference/string/string/
James


#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
#include <stdexcept>

class BadConversion : public std::runtime_error {
public:
   BadConversion(std::string const& s)
     : std::runtime_error(s)
     { }
};

template<typename T>
inline std::string stringify(T const& x)
{
   std::ostringstream o;
   if (!(o << x))
     throw BadConversion(std::string("stringify(")
                         + typeid(x).name() + ")");
   return o.str();
}


int main (int argc, char** argv)
{
   std::string  S1;
   std::string  S2;
   long     hwnd;
  hwnd=12345;
  S1 = "Window Handle = ";
  S1+= stringify(hwnd);
  std::cout << S1 << std::endl;
  return 0;
}


Title: Re: My first steps with C++
Post by: James C. Fuller on July 31, 2010, 02:11:15 PM
Patrice,
 As a follow up this is the Bcx code I used to obtain the previous.
Here I used the $SOURCE directive which includes the commented Bcx code in
the cpp source.(it seems to have a problem with double colons)
Also note the $CCODE This allows c/c++ "as is" in your source;so if I fine a piece of code I want to use, no translating it first.
James

Bcx Code:


$NOMAIN
$ONEXIT "GCTD.BAT $FILE$ -m32"
$CPP
$CCODE
// File: convert.h
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
#include <stdexcept>

class BadConversion : public std::runtime_error {
public:
  BadConversion(std::string const& s)
    : std::runtime_error(s)
    { }
};

template<typename T>
inline std::string stringify(T const& x)
{
  std::ostringstream o;
  if (!(o << x))
    throw BadConversion(std::string("stringify(")
                        + typeid(x).name() + ")");
  return o.str();
}
$CCODE

$SOURCE
Function main( argc As Integer,argv As char Ptr Ptr)
Raw S1 As std::string
Raw S2 As std::string

Raw hwnd As long
hwnd = 12345


S1 = "Window Handle = "
S1 += stringify(hwnd)

std::cout << S1 << std::endl
End Function
$SOURCE



cpp code:

// *********************************************************************
// Created with BCX32 - BASIC To C/C++ Translator (V) 6.1.5 (2010/07/29)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C++ Compiler
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <wchar.h>      // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <conio.h>
#include <direct.h>
#include <ctype.h>
#include <io.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <stdarg.h>
#include <process.h>
// *************************************************

// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
 #define overloaded
 #define C_EXPORT EXTERN_C __declspec(dllexport)
 #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
 #define C_EXPORT __declspec(dllexport)
 #define C_IMPORT __declspec(dllimport)
#endif

// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
 #define atanl atan
 #define sinl  sin
 #define cosl  cos
 #define tanl  tan
 #define asinl asin
 #define acosl acos
 #define log10l log10
 #define logl   log
 #define _fcloseall fcloseall
#endif

// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
 // ===== Borland Libraries ==========
 #include <dos.h>
 #pragma comment(lib,"import32.lib")
 #pragma comment(lib,"cw32.lib")
 // ==================================
#endif

// Microsoft VC++
#ifndef DECLSPEC_UUID
 #if (_MSC_VER >= 1100) && defined ( __cplusplus )
   #define DECLSPEC_UUID(x)    __declspec(uuid(x))
 #else
   #define DECLSPEC_UUID(x)
 #endif
#endif


#if !defined( __LCC__ )
// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************
#endif
//               User Prototypes
// *************************************************


int     main (int, char** );


// *************************************************
//            User Global Initialized Arrays
// *************************************************


// File: convert.h
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
#include <stdexcept>

class BadConversion : public std::runtime_error {
public:
  BadConversion(std::string const& s)
    : std::runtime_error(s)
    { }
};

template<typename T>
inline std::string stringify(T const& x)
{
  std::ostringstream o;
  if (!(o << x))
    throw BadConversion(std::string("stringify(")
                        + typeid(x).name() + ")");
  return o.str();
}
// [S01.BAS - 32] Function main( argc As Integer,argv As char Ptr Ptr)

// *************************************************
//                 Runtime Functions
// *************************************************


// ************************************
//       User Subs and Functions
// ************************************


int main (int argc, char** argv)
{
// [S01.BAS - 33] Raw S1 As stdnnstring
  std::string  S1;
// [S01.BAS - 34] Raw S2 As stdnnstring
  std::string  S2;
// [S01.BAS - 36] Raw hwnd As long
  long     hwnd;
// [S01.BAS - 37] hwnd = 12345
 hwnd=12345;
// [S01.BAS - 40] S1 = "Window Handle = "
 S1="Window Handle = ";
// [S01.BAS - 41] S1 += stringify(hwnd)
 S1+=stringify(hwnd);
// [S01.BAS - 43] stdnncout << S1 << stdnnendl
 std::cout<<S1<<std::endl;
// [S01.BAS - 44] End Function
 return 0;
}




Title: Re: My first steps with C++
Post by: Patrice Terrier on July 31, 2010, 10:06:02 PM
James,

I have made some good progress using:
Quote#include <iostream>
#include <string.h>
using namespace std;

altogether with sprintf_s, this way:
Quotestring Msg = "Window";
char szStr[12];
sprintf_s(szStr, "% d ", hWnd);
Msg += szStr;
zTrace(Msg);

and i have changed my zTrace.h to this:
//#include <windows.h>
//#include <tchar.h>
//
//#include <iostream>
//#include <string.h>
//using namespace std;

//void zTrace(char szMsg[])
void zTrace(string sMsg)
{
   static HMODULE hDLL;
   typedef int (__stdcall *ZTRACE) (char*);
   ZTRACE hPROC;

   if (!hDLL)
      hDLL = LoadLibrary(L"zTrace");//_T("zTrace.dll"));
   if (hDLL)
   {
      hPROC = (ZTRACE) GetProcAddress(hDLL, "zTrace");
      if (hPROC)
      {
        //int nRet = hPROC(szMsg);
        int nRet = hPROC((char*) sMsg.c_str());
      }
      else
      {
        FreeLibrary(hDLL);
      }
   }
}


In the source code, note: int nRet = hPROC((char*) sMsg.c_str()); that allows me to convert a the sMsg string, back to asciiz pointer.

...
Title: Re: My first steps with C++
Post by: James C. Fuller on August 01, 2010, 03:18:00 PM
I don't think sprintf_s is part of the standard C library so is not portable.

I am using the latest MinGWTD 32/64 compiler.

James

Title: Re: My first steps with C++
Post by: Patrice Terrier on August 01, 2010, 03:43:09 PM
James,

So far, i am focusing on Microsoft C and C++, because i am a Windows SDK programmer only.

:)
Title: Re: My first steps with C++
Post by: James C. Fuller on August 01, 2010, 05:21:16 PM
Quote from: Patrice Terrier on August 01, 2010, 03:43:09 PM
James,

So far, i am focusing on Microsoft C and C++, because i am a Windows SDK programmer only.

:)

There are a number of Windows C++ compilers. Why paint yourself into a corner by using non-standard code when alternatives exist?

James
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 01, 2010, 06:01:02 PM
James,

Well i would rather say that (by me) VISUAL STUDIO is THE standard ;)

and i can use either sprintf or sprintf_s

However, when using sprintf alone i got this warning message from VS2010:
Quotewarning C4996: 'sprintf':
This function or variable may be unsafe. Consider using sprintf_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
See online help for details.   c:\vs2005\hellowin32\hellowin32\hellowin32.cpp
Title: First try to skin a C++ Win32 window
Post by: Patrice Terrier on August 02, 2010, 03:30:48 PM
Here is my first try to skin a Win32 C++ window.


      string SkinTheme = ExePath();
      SkinTheme += "Sony.sks";
      if (skInitEngine (SkinTheme, ""))
      {
        skSkinWindow(hWnd, "Dock|Undock|Minimize|Maximize|Restore|Close");
      }

      ShowWindow(hWnd, nCmdShow);
      UpdateWindow(hWnd);
   
      // Main message loop
      while (GetMessage(&msg, NULL, 0, 0))
      {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
      }


Two new functions:

string FullExeName()
{
    string sResult;
    char exepath[MAX_PATH];
    if (GetModuleFileNameA(0, exepath, sizeof(exepath)))
    {
        sResult = exepath;
    }
    return sResult;
}

string ExePath()
{
    string sResult;
    char exepath[MAX_PATH];
    if (GetModuleFileNameA(0, exepath, sizeof(exepath)))
    {
        sResult = exepath;
        sResult = sResult.substr( 0, sResult.rfind("\\"));
        sResult += "\\";
    }
    return sResult;
}


One new include file:

#include <windows.h>
//
#include <iostream>
#include <string.h>

HMODULE g_hWLFTdll;

int skInitEngine(std::string skinfile, std::string suserkey)
{
    int nRet = 0;

    if (!g_hWLFTdll)
        g_hWLFTdll = LoadLibrary(L"WinLIFT");

    if (g_hWLFTdll)
    {
        typedef int (__stdcall *skProc) (char*, char*);
        skProc hPROC;
        hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skInitEngine");
        if (hPROC)
        {
            nRet = hPROC((char*) skinfile.c_str(), (char*) suserkey.c_str());
        }
        else
        {
            FreeLibrary(g_hWLFTdll);
        }
    }
    return nRet;
}

int skSkinWindow(HWND hWnd, std::string sbuttontip)
{
int nRet = 0;

    if (g_hWLFTdll)
    {
        typedef int (__stdcall *skProc) (HWND, char*);
        skProc hPROC;
        hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinWindow");
        if (hPROC)
        {
            nRet = hPROC(hWnd, (char*) sbuttontip.c_str());
        }
    }
    return nRet;
}



I have learned also how to use the #include directive:
Added:
The size of the resulting EXE in relase mode is 13,312 bytes.


...
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 02, 2010, 08:05:06 PM
Until now i had always translated from C++ to PB, but doing the reverse is a good experience, that helps me to understand the idiosyncrasy of the C++ syntax.   :)


Here is an example of header translation:
#include <windows.h>
//
#include <iostream>
#include <string.h>

#define WM_SKGETMENUICON (WM_USER + WM_GETICON)

// Anchor constants
#define ANCHOR_NONE                0
#define ANCHOR_LEFT                ANCHOR_NONE
#define ANCHOR_WIDTH               1
#define ANCHOR_RIGHT               2
#define ANCHOR_CENTER_HORZ         3
#define ANCHOR_HEIGHT              4
#define ANCHOR_HEIGHT_WIDTH        5
#define ANCHOR_HEIGHT_RIGHT        6
#define ANCHOR_BOTTOM              7
#define ANCHOR_BOTTOM_WIDTH        8
#define ANCHOR_BOTTOM_RIGHT        9
#define ANCHOR_CENTER_HORZ_BOTTOM  10
#define ANCHOR_CENTER_VERT         11
#define ANCHOR_CENTER_VERT_RIGHT   12
#define ANCHOR_CENTER              13

// Use this value in the optional GMToffset parameter to disable local timer in case of animated background
#define DISABLE_TIMER              99

HMODULE g_hWLFTdll;

// Init the WinLIFT SkinEngine
int skInitEngine(std::string skinfile, std::string suserkey) {
   int nRet = 0;

   if (!g_hWLFTdll)
       g_hWLFTdll = LoadLibrary(L"WinLIFT");

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (char*, char*);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skInitEngine");
       if (hPROC) {
           nRet = hPROC((char*) skinfile.c_str(), (char*) suserkey.c_str());
       }
       else {
           FreeLibrary(g_hWLFTdll);
       }
   }
   return nRet;
}

// The main function to skin a window
int skSkinWindow(HWND hWnd, std::string sbuttontip) {
int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, char*);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinWindow");
       if (hPROC) {
           nRet = hPROC(hWnd, (char*) sbuttontip.c_str());
       }
   }
   return nRet;
}

// Disable skinning of a specific control
int skSkinDisable(HWND hCtrl) {
int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinDisable");
       if (hPROC) {
           nRet = hPROC(hCtrl);
       }
   }
   return nRet;
}

// Enable skinning of a specific control (use it only after a previous call to skSkinDisable)
int skSkinEnable(HWND hCtrl) {
int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinEnable");
       if (hPROC) {
           nRet = hPROC(hCtrl);
       }
   }
   return nRet;
}

// Anchor child controls
int skSetAnchorCtrl(HWND hCtrl, int AnchorMode) {
int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, int);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSetAnchorCtrl");
       if (hPROC) {
           nRet = hPROC(hCtrl, AnchorMode);
       }
   }
   return nRet;
}

// 4.73 Animated clock control
HWND skClockCtrl (
   HWND hOwner,                     // Handle of the window parent owner.
   std::string sImageFile,          // Full path name to the clock image background.
   int x,                           // X location of the clock control.
   int y,                           // Y location of the clock control.
   int w,                           // Width of the clock control.
   int h,                           // Height of the clock control.
   int ButID,                       // Unique ID of the clock control.
   int ARGB1,                       // The color to draw the Hour/Minute hands.
   int ARGB2,                       // The color to draw the second hands.
   int GMToffset ) {                // The GMT offset to be used.

HWND hCtrl = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, char*, int, int, int, int, int, int, int, int);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skClockCtrl");
       if (hPROC) {
           hCtrl = (HWND) hPROC(hOwner, (char*) sImageFile.c_str(), x, y, w, h, ButID, ARGB1, ARGB2, GMToffset);
       }
   }
   return hCtrl;    
}

// Create Tooltip.
HWND skCreateToolTip (
   HWND hCtrl,                      // Handle of the child control.
   std::string sText) {             // The text to display.

HWND hTooltip = 0;

if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, char*);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skCreateToolTip");
       if (hPROC) {
           hCtrl = (HWND) hPROC(hCtrl, (char*) sText.c_str());
       }
   }
   return hCtrl;
}

// Assign new tooltip text to control.
void skSetToolTipText (
   HWND hCtrl,                      // Handle of the child control.
   std::string sText) {             // The new text to display.

if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, char*);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSetToolTip");
       if (hPROC) {
           (HWND) hPROC(hCtrl, (char*) sText.c_str());
       }
   }
}

// Get the tooltip text of a specific control.
string skGetToolTipText (
   HWND hCtrl) {                    // Handle of the child control.

std::string sText;

if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSetToolTipText");
       if (hPROC) {
           sText = (char*) hPROC(hCtrl);
       }
   }

return sText;
}


And did i say, i am glad to have learned SDK programming to perform the conversion  :D

...
Title: Re: My first steps with C++
Post by: Jürgen Huhn on August 02, 2010, 08:48:55 PM
QuoteUntil now i had always translated from C++ to PB, but doing the reverse is a good experience, that helps me to understand the idiosyncrasy of the C++ syntax.

That`s same what i`ve learned even in this Disscussion... :)

..
Title: Passing variable by reference
Post by: Patrice Terrier on August 03, 2010, 10:50:38 AM
Example on how to pass variable by reference:

QuoteHWND hCtrl = ...;
int nMin = 0, nMax = 0;
skGaugeGetMinMax(hCtrl, nMin, nMax);

// Retrieve the Min/Max gauge value (passing variable by reference).
void skGaugeGetMinMax (
   HWND hCtrl,                      // The control handle.
   int &nMin,                       // Minimum value (for knob this is a rotation angle in the range 0-359).
   int &nMax                        // Maximum value (for knob this is a rotation angle in the range 0-359).
   ) {
   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, int*, int*);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skGaugeGetMinMax");
       if (hPROC) {
           hCtrl = (HWND) hPROC(hCtrl, &nMin, &nMax); // Passage by reference.
       }
   }
}
Title: Re: My first steps with C++
Post by: Jürgen Huhn on August 03, 2010, 12:40:03 PM
QuoteI have learned also how to use the #include directive:

   * #include <windows.h> // With <>, search along the path.
   * #include "WinLIFT.h"  // With "", search in the same directory of the current file.

Patrice,

thank you for sharing your Experiences. Thank`s for this include syntax!!
I want to give you a feedback for your Information that there is anyone who listen and want to learn.
Then i remember to another topic where do you told me that no one listen and we are alone, you and me..
But when i look on the Count how many user read the Thread then i think sometimes about over thousand user`s and
no one reply. Only a Hand full nice People who say`s thank`s. We know them, there`re always the same.
Sometimes the posts not really needed, to much or not by the topic, but you have a face of them.
Personally i get nearly every Day nice eMails with Question`s and many thank`s to me.
Today for example, from Gary Beene and Chris Boss for to have inspired Chris enough to give OpenGL a try with PB.

Back to the topic, because i really read your tranlations. For clarity or levelheadedness i need to
correct one of your statements especial for beginners in programming general or i need to revise my knowlege.

QuoteHere is an example of header translation:

I think is a mix of headers an Functions.. It`s ok because the Header`s are defined before the Function`s use them.
The Headers are the Definitition`s of Constants, Datatypes and Com Objects or GUID`s.

Like this in your translation:

#include <windows.h>
//
#include <iostream>
#include <string.h>

Your own definition`s:

#define WM_SKGETMENUICON (WM_USER + WM_GETICON)

// Anchor constants
#define ANCHOR_NONE                0
#define ANCHOR_LEFT                ANCHOR_NONE
#define ANCHOR_WIDTH               1
#define ANCHOR_RIGHT               2
#define ANCHOR_CENTER_HORZ         3
#define ANCHOR_HEIGHT              4
#define ANCHOR_HEIGHT_WIDTH        5
#define ANCHOR_HEIGHT_RIGHT        6
#define ANCHOR_BOTTOM              7
#define ANCHOR_BOTTOM_WIDTH        8
#define ANCHOR_BOTTOM_RIGHT        9
#define ANCHOR_CENTER_HORZ_BOTTOM  10
#define ANCHOR_CENTER_VERT         11
#define ANCHOR_CENTER_VERT_RIGHT   12
#define ANCHOR_CENTER              13

And this is a Function:

// Disable skinning of a specific control
int skSkinDisable(HWND hCtrl) {
   int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinDisable");
       if (hPROC) {
           nRet = hPROC(hCtrl);
       }
   }
   return nRet;
}

Or is it wrong??

The translation is good!! Ich könnte das nicht besser machen...

I`m also not an Expert for C/C++, but i use the Compilers which enjoys all the advantages about years.
You`re not so near at the Code like in Powerbasic.. You have a UserInterface(Visual), wich generating, translating,
dissasemle and debuging the Code build on Classes with a large Pool of Tools and so on ..
You don`t need to take a look into the Code, if you`re only work in a Visual Studios.

Do you think i missunderstood something?

And do you have the Debugging allways switched on for every running Program at any time your Computer is on?

I had also another Question, but forgot it over this.. :-X later..

All  my Best,

Jürgen  :)  :)
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 03, 2010, 02:08:41 PM
Jürgen,

Thanks for the feedback.

You wrote:
QuoteAnd this is a Function:

// Disable skinning of a specific control
int skSkinDisable(HWND hCtrl) {
  int nRet = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skSkinDisable");
       if (hPROC) {
           nRet = hPROC(hCtrl);
       }
   }
   return nRet;
}

I would rather say: it is the "explicit" C++ counterpart declaration for this WinLIFT API PB's declaration:
Quote' Disable skinning of a specific control
 DECLARE FUNCTION skSkinDisable LIB "WinLIFT.dll" ALIAS "skSkinDisable" ( _
 BYVAL hCtrl AS LONG _              ' Handle of the child control to disable.
 ) AS LONG

Thus for me this C++ "WinLIFT.h" header, is to serve the same purpose that the PB's "WinLIFT.inc" include file.

I did it this way, because i was unable to use "implicit" linking with my PBwin32 DLL.

...
Title: Re: My first steps with C++
Post by: Jürgen Huhn on August 03, 2010, 02:47:56 PM
Of course Patrice,

and for your Code i`ll be sure on the best Place!
But it`s technical a Function with an input and an output Value. Did you don`t ask your self,
maybe there is behind the DECLARE statement of Powerbasic the same??
Even only such a Function..   

We have the Procadress of the Library, the intput and the output definition as Types ???


Title: Re: My first steps with C++
Post by: Patrice Terrier on August 03, 2010, 05:51:13 PM
Quotemaybe there is behind the DECLARE statement of Powerbasic the same

Perhaps...

As a matter of comparison, here are several declaration examples of the same WinLIFT API:

PowerBASIC
Quote  DECLARE FUNCTION skKnobGauge LIB "WinLIFT.dll" ALIAS "skKnobGauge" ( _
 BYVAL hOwner AS LONG, _            ' Handle of the window parent owner.
 zFullpathImageName AS ASCIIZ, _    ' Full path name to the gauge image.
 BYVAL x AS LONG, _                 ' X location of the gauge control.
 BYVAL y AS LONG, _                 ' Y location of the gauge control.
 BYVAL W AS LONG, _                 ' Width of the gauge control.
 BYVAL H AS LONG, _                 ' Height of the gauge control.
 BYVAL ButID AS LONG, _             ' Unique ID of the gauge control.
 BYVAL MinValue AS LONG, _          ' MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
 BYVAL MaxValue AS LONG, _          ' MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
 BYVAL UsePos AS LONG, _            ' 0 or initial angle value in degree to use.
 BYVAL Reserved AS LONG _           ' Must be NULL.
 ) AS LONG

WinDev
QuotePROCEDURE skKnobGauge( ...      
LOCAL hParent is int, ...       // Handle of the window parent owner.                                                
LOCAL sImagePath is string, ... // Full path name to the gauge image.                                                  
LOCAL x is int, ...             // X location of the gauge control.                                                  
LOCAL y is int, ...             // Y location of the gauge control.                                                  
LOCAL w is int, ...             // Width of the gauge control.                                                        
LOCAL h is int, ...             // Height of the gauge control.                                                      
LOCAL nID is int, ...           // Unique ID of the gauge control.                                                    
LOCAL MinValue is int, ...      // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
LOCAL MaxValue is int, ...      // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
LOCAL UsePos is int, ...        // 0 or initial angle value in degree to use.                                        
LOCAL reserved is int ...       // Must be NULL.                                                                      
)
nRet is int = API(WinLIFT, "skKnobGauge", hParent, (sImagePath), x, y, w, h, nID, MinValue, MaxValue, UsePos, reserved)
RESULT nRet

C++
QuoteHWND skKnobGauge (
   HWND hOwner,                     // Handle of the window parent owner.
   std::string sImageFile,          // Full path name to the gauge image.
   int x,                           // X location of the gauge control.
   int y,                           // Y location of the gauge control.
   int w,                           // Width of the gauge control.
   int h,                           // Height of the gauge control.
   int ButID,                       // Unique ID of the gauge control.
   int MinValue,                    // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
   int MaxValue,                    // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
   int UsePos,                      // 0 or initial angle value in degree to use.
   int Reserved                     // Must be NULL.
   ) {
   HWND hCtrl = 0;

   if (g_hWLFTdll) {
       typedef int (__stdcall *skProc) (HWND, char*, int, int, int, int, int, int, int, int, int);
       skProc hPROC = (skProc) GetProcAddress(g_hWLFTdll, "skKnobGauge");
       if (hPROC) {
           hCtrl = (HWND) hPROC(hOwner, (char*) sImageFile.c_str(), x, y, w, h, ButID, MinValue, MaxValue, UsePos, Reserved);
       }
   }
   return hCtrl;    
}

C#
Quote[DllImport(WINLIFT)]
public static extern IntPtr skKnobGauge (
IntPtr hOwner,           // Handle of the window parent owner.
string zFullpath,        // Full path name to the gauge image.
int x,                   // X location of the gauge control.
int y,                   // Y location of the gauge control.
int w,                   // Width of the gauge control.
int H,                   // Height of the gauge control.
int ButID,               // Unique ID of the gauge control.
int MinValue,            // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
int MaxValue,            // MAXIMUM range value (the exclusion zone is between the MINIMUM and MAXIMUM range).
int UsePos,              // 0 or initial angle value in degree to use.
int Reserved AS LONG     // Must be NULL.
);


This type of API encapsulation allows me to port easily my code from one language to another.

...
Title: Re: My first steps with C++
Post by: Jürgen Huhn on August 03, 2010, 06:31:02 PM
Yes Patrice it must be so...

Do you have the Recources (Code) and you`re be able to write a little Function to read only the Proc Declarations for the Lib
from file as String and do the Implizit linking with your DLL from the strings in the file.  The include Routine of Visual C++ has sadly no
support for the Powerbasic .inc but nothing else is done wit other Languages by Visual C++.. ;)
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 06, 2010, 09:33:39 PM
Translating my fiirst WinLIFT/GDImage project (HUDplus) to Visual Studio 2010.

That's a very good training to learn the C++ syntax.  8)

...

Title: Re: My first steps with C++
Post by: James C. Fuller on August 07, 2010, 10:52:16 AM
Patrice,
 It may be possible to use Bcx3264 to help you in your conversions.
Here is Bcx3264 code and partial c++ code listing.
This is not a standard bcx conversion but is part of the Bcx3264 package.
the var types in the Import block must be c types.

James


#include "C:/bcx/include/Bcx3264.h"
CPP
NOMAIN

Import sqlite3 c_declare
sqlite3_open(a As const char*,b As long*) As int
sqlite3_close(a As long) As int
sqlite3_errmsg(b As long) As char*
sqlite3_exec(a As long,b As char*,c As void*,d As void*,e As char**) As int
sqlite3_free(a As void*) As void
sqlite3_libversion(a As void) As char*
End Import

Function main( argc As Integer,argv As char Ptr Ptr)
Dim As Long db
Raw As Integer rv
Dim v$
rv = sqlite3_open("jcf77.sdb",&db)


Print "rv = ",rv
v$ = sqlite3_libversion()
Print v$
sqlite3_close(db)

End Function


converted c++ code

// *************************************************
//          User Defined Types And Unions
// *************************************************
typedef int  (__cdecl *BCXFPROT1)(const char*,long*);
typedef int  (__cdecl *BCXFPROT2)(long);
typedef char*  (__cdecl *BCXFPROT3)(long);
typedef int  (__cdecl *BCXFPROT4)(long,char*,void*,void*,char**);
typedef void (__cdecl *BCXFPROT5)(void*);
typedef char*  (__cdecl *BCXFPROT6)(void);

// *************************************************
//                System Variables
// *************************************************

static BCXFPROT1 sqlite3_open;
static BCXFPROT2 sqlite3_close;
static BCXFPROT3 sqlite3_errmsg;
static BCXFPROT4 sqlite3_exec;
static BCXFPROT5 sqlite3_free;
static BCXFPROT6 sqlite3_libversion;

.........................

int main (int argc, char** argv)
{

HMODULE  H_SQLITE3 = LoadLibrary("sqlite3.dll");
sqlite3_open=(BCXFPROT1)GetProcAddress(H_SQLITE3, "sqlite3_open");
sqlite3_close=(BCXFPROT2)GetProcAddress(H_SQLITE3, "sqlite3_close");
sqlite3_errmsg=(BCXFPROT3)GetProcAddress(H_SQLITE3, "sqlite3_errmsg");
sqlite3_exec=(BCXFPROT4)GetProcAddress(H_SQLITE3, "sqlite3_exec");
sqlite3_free=(BCXFPROT5)GetProcAddress(H_SQLITE3, "sqlite3_free");
sqlite3_libversion=(BCXFPROT6)GetProcAddress(H_SQLITE3, "sqlite3_libversion");

// ****************************************


Title: Re: My first steps with C++
Post by: Patrice Terrier on August 07, 2010, 02:35:24 PM
James,

Thank you.

Indeed i am almost done with my conversion.
Knowing C#, and having translated much C and C++ code to PB (like Direct2D), helped me much.

I am porting WinLIFT and GDImage to c++, because i am looking for new market opportunities.  ;)

I shall post the HUDplus c++ source code project here, once done, to share what i have learned.

...
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 08, 2010, 10:21:53 AM
I have completed the translation of my PB's HUDplus project to C++,
and the size of the resulting executable are:

PowerBASIC: 30720 bytes.

C++ with /Ox (full optimization): 30720 bytes.
C++ with /O1 (size reduction): 25088 bytes.
C++ with /O2 (speed boost): 30720 bytes.

Thus, i would say, PB does already a pretty good job.  8)

Added:
forget to say that Viual Studio IntelliSense is a wonderful tool for a beginner like me.  ;)

...
Title: Re: My first steps with C++
Post by: Peter Weis on August 09, 2010, 01:00:32 PM
Hi Patrice,
I do not think that you are a beginner! 're Fully fit on it. I would not get out so quickly. I have 15 years no C + + programming!
The 5 Kb size reduction with less power compared to Basic. Expected from the string of motor PowerBasic come.

Regards Peter
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 09, 2010, 03:55:21 PM
Peter--

I am learning C++, because i think there will be more people interrested by WinLIFT and GDImage in the Microsoft's galaxy than in the PB's world.

Indeed, i should have learned C++ much sooner.  :-[

...
 
Title: Re: My first steps with C++
Post by: Peter Weis on August 09, 2010, 05:52:28 PM
Hi Patrice, :)
With c or c + + is open to you in any case the 64 bit world. That is in Power Basic unfortunately not the case. I like c actually not so. Better to assembler because I have the full control. Could I still think that you Winlift gdiimage and completely to C + + portierst, then you had a Complete encapsulation. You could then Winlift Gdiimage or use of different windows with different properties. Without which they influence each other.
z.B Winlift a class and a class gdiimage. Each class has it's own instancen. You can call several times each class! :D
 
 
Regards Peter
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 09, 2010, 06:17:07 PM
Peter--

Actually, my plan was to enable the use of WinLIFT and GDImage altogether with C++ 32-bit, thus the first thing was to provide the correct API headers.

But in the long run, when i become more familiar with C++, i shall probably create the 64-bit version with Visual Studio (because 64-bit is my main motivation to learn C++).

...
Title: Re: My first steps with C++
Post by: Peter Weis on August 13, 2010, 12:23:09 AM
Hi Patrice, ;)

I see this, too! You can of course at the moment only with C + +, C, Assembler, Delphi or Visual Net (Basic) or PureBasic to achieve a 64 connection. Hope I did not forget any language! It would of course not bad in a complete encapsulation of gdimage and think Windlift. This is only possible when you put it in the above mentioned programming languages object oriented programm for new. This would go well with Power Basic 9.0, but unfortunately only 32 bits :'(.

But whom do you need a 64 bit connection, you will sooner or later anyway and gdimage winlift need to write new Who there in the foreseeable future, no 64-bit Power Basic.

I would like to open up any new 64-bit debate. It took me quite annoyed last month the discussions that have run here and in other forums.

Regards Peter
Title: Re: My first steps with C++
Post by: Jürgen Huhn on August 13, 2010, 05:40:36 PM
Hallöchen Peter,

i think PowerBasic has the Choice beetween to take the Train into the Future or to sink and to fade away sooner or later.
I`m also on the way to use more and more 64bit-Compiler and 64bit Datatypes to work with the gain of 64bit advantage.
To produce a Software wich must support the full access to newer Hardware no other option remains.

I hope "PB Win 64bit" soon comes!

Gruß, Jürgen..
Title: Re: My first steps with C++
Post by: Frederick J. Harris on August 31, 2010, 08:25:00 PM
Hello Patrice!

       I'm sorry I missed your start of your C++ posts and endeavors!  All of July and a good bit of August I wasn't on the internet very much, as I was working hard at converting one of my eMbedded C++ projects over to Visual Studio C++ 2008.  Anyway, I didn't know the answer to your implicit linking question, as I had always done explicit linking.  However, regarding your questions about strings, years ago I started using my own string class I built myself.  I never fooled with C++'s string classes for various reasons.  I'll attach (pkzip file) a Visual Studio 2008 C++ project that exercises my string class some.  It uses Left, Right, Mid, InStr, Parse, etc.  Like you, I pretty much think in basic too.  You are certainly welcome to it if it would be of any help to you.  One of the reasons I use my own string class, other than that I like basic syntax, is that it doesn't add much to an executables size - only a couple k.  Microsoft has cleaned up their act quite a bit with string handling.  With Visual Studio 6 you had to include support for MFC to get their String class, and that added about 1M to an exes size, and for me that was much too high a price to pay.  Lately, things aren't so bad, but I still prefer my own class.  I've gotta say, I code in C++ just about the same as in PowerBASIC.  I really only use C++ classes for a few things.  Its worked pretty good for my string class and my ODBC wrapper class, and to tell the truth, that's about it.  I don't care for Windows Class Libraries at all.
Title: Re: My first steps with C++
Post by: Patrice Terrier on August 31, 2010, 09:44:25 PM
Ed,

Thank you for the ZIP file.

I have used the VS2010 string class, because it is very close to the C# and the WinDev syntax i know already.
In release mode, i can produce a code size that is almost the same than in PB, and that is what i wanted.

I avoid to use the C++ CRL, and stay as close as possible to pure C, using always __stdcall and char* for compatibility with my PBwin DLL.
And using of course only the flat API, to easily translate my code from one language to the other.

I have a question about your use of the const keyword before the parameters being passed to your procedures, do you use it as a BYVAL equivalent, or what?

...
Title: Re: My first steps with C++
Post by: Frederick J. Harris on August 31, 2010, 10:03:19 PM
The const keyword in C/C++ is very important.  If a parameter is declared as a const then any attempt to alter it in the procedure will be caught by the compiler.  I wouldn't say there is any relation ship to that and the PowerBASIC Byval override.

Where const really comes into its own in C++ is with reference parameters.  C didn't have reference parameters (had to pass pointers by value) but their addition to the C++ language was one of the major additions besides classes.  As you know, passing a reference in PowerBASIC or C++ is very advantaegous because no matter how large the object is, all that is really being pushed on the stack is a pointer - so its very fast.  The danger of passing a reference though in the case where you only want the data used - not modified, is that since the procedure has its address, it could be modified - bad if you don't want that.  So if you place the const keyword in front of a reference parameter you'll have the best of both worlds - fast parameter passing, and no chance of the data being inadvertantly modified.  I think you could say its a rather important C++ concept.

Title: Re: My first steps with C++
Post by: Patrice Terrier on August 31, 2010, 11:25:19 PM
Ed

Thus, the const keyword is suitable for the case of pointer (when a parameter is passed by reference) that you don't want to change, ok.

Then it is like byval, but without pushing the value on the stack ;)

...




Title: Re: My first steps with C++
Post by: Frederick J. Harris on September 01, 2010, 05:02:56 PM
Quote
Then it is like byval, but without pushing the value on the stack

Yes, except I hate the comparison with byval because to me that implies a copying of data so that the function is working with a temporary copy the compiler created behind the scenes. 

I believe the only way you can create a similiar situation in PowerBASIC where you pass a reference to an object instead of a copy and the object can't be changed is if the object is an equate.  That's a bit limiting because you can't really modify an equate anywhere in a program once its been assigned.  Here's a little C++ program with output afterwards that shows that you can have a struct variable (Employee e1) that can be passed to two similiar functions - one as a const& and another where it can be modified...


#include <stdio.h>
#include <string.h>


struct Employee
{
unsigned iEmpNum;
unsigned iClassification;
double   dblSalary;
char     szName[64];
}; 


void SomeFunction1(const Employee& emp)
{
printf("In SomeFunction1 With const Employee Reference\n");
//emp.dblSalary=75000.01;        //unremark to produce compile error
}


void SomeFunction2(Employee& emp)
{
printf("In SomeFunction2 With Employee Reference\n");
emp.dblSalary=75000.01; 


 
int main(int argc, char *argv[])
{
Employee e1;

e1.dblSalary=60000.00,  e1.iClassification=2, e1.iEmpNum=2, strcpy(e1.szName,"John Doe");
SomeFunction1(e1);
SomeFunction2(e1);
getchar();

return 0;
}

//In SomeFunction1 With const Employee Reference
//In SomeFunction2 With Employee Reference



Interestingly, functions can be overloaded based on the const keyword.  To C++ two functions of the exact same name and parameter list differing only in the const keyword are two different functions.  Take a look at this...


#include <stdio.h>
#include <string.h>


struct Employee
{
unsigned iEmpNum;
unsigned iClassification;
double   dblSalary;
char     szName[64];
}; 


void SomeFunction(const Employee& emp)
{
printf("In SomeFunction With const Employee Reference\n");
//emp.dblSalary=75000.01;
}


void SomeFunction(Employee& emp)
{
printf("In SomeFunction With Employee Reference\n"); 
}

 
int main(int argc, char *argv[])
{
const Employee e1 = {1, 1, 75000.00, "Jim Smith"};
Employee e2;

e2.dblSalary=60000.00,  e2.iClassification=2, e2.iEmpNum=2, strcpy(e2.szName,"John Doe");
SomeFunction(e1); 
SomeFunction(e2);
getchar();

return 0;
}


//In SomeFunction With const Employee Reference
//In SomeFunction With Employee Reference


Title: Re: My first steps with C++
Post by: Patrice Terrier on August 11, 2011, 02:50:54 PM
The ZIP files attached to the posts of this thread have been updated, to fix the ZIP file corruption caused by the "Server Collapse".

...
Title: Re: My first steps with C++
Post by: James C. Fuller on December 10, 2012, 01:10:01 PM
Patrice,
  It just so happens I am working on a tutorial for Bc9(bcx) to illustrate calling a function in a dll which
in turn does a callback to the app, using a variaty of __cdecl and __stdcall functions.
I am showing this for both MinGW g++ 32/64 and VC++ 32/64.

As I mentioned in the other thread I uninstalled Visual Studio Express as it will only let you compile to 32bit without
a lot of hacking. You should not have a problem with one of the paid versions. I suggest not using the VS IDE.

I have only done this with the Win7.1 SDK on Win7 64. I don't know what Sdk Visual Studio installed on your machine.
Do you have this?
From Start menu -> All Programs -> Microsoft Windows SDK v7.1 -> Windows SDK 7.1 Command Prompt

If so we should be golden.

James





Title: Re: My first steps with C++
Post by: Patrice Terrier on December 10, 2012, 03:54:00 PM
James

I already have SDK 7.0A, i shall follow your advice, and install SDK 7.1
Title: Re: My first steps with C++
Post by: Patrice Terrier on December 10, 2012, 06:55:11 PM
James--

Spend all the afternoon to patch VS2010 to the latest, and installing SDK 7.1 that failed 3 times before i could figure from Google what to do (had to uninstall first the redistributable package that was installed by another software before i could succeed with SDK 7.1, a real pain).

Anyway now i should be up and running, and this story is another good reason why i want to go full SDK to avoid the need to install any redistributable runtime.

...
Title: Re: My first steps with C++
Post by: James C. Fuller on December 10, 2012, 08:26:41 PM
Patrice,
  The main element for compiling from the command line is SetEnv.cmd located here on my Win7 64:
  C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd
A very interesting read. take a look when you get time.

The shortcut from the Start Button is:
C:\Windows\System32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd"

When you select it you end up with the default -> 64 bit Debug mode.

You do NEED to spawn a new cmd processor as SetEnv.cmd needs the /V:ON which is usually off by default on most systems.
The /T:0E is for the yellow on black color and /E:ON is for command extensions which are on by default I believe.

I call it from a bat file so I can set it to anything I want.

So from a REGULAR command prompt (not the SDK 7.1) or a shell from your editor:

cmd.exe /V:ON /K VC.BAT <your file no extension cpp assumed> [X86 Or X64] [con gui dll] [Release Debug]

Example To compile MyTestDll_32.cpp to a 32bit dll Release build:
"cmd.exe /V:ON /K VC.BAT MyTestDll_32 X86 dll Release"

I just recently discovered how to do this from anta40 on hutch's Masm board.
He did not use any parameters for cl nor have I here. I'm sure you are knowledgeable enough to figure out what you might
want and add them.

My batch file.
First parameter is the source file name.
I always call it from the source directory but RadAsm3 adds the full path when calling so I strip off the
full path and use just the file name in the bat file -> SET F=%~n1
Also note it will automatically compile and link an rc file with the same name as the c++ source.
It will even search a res\ directory if you prefer to keep all your resources (icon's, pictures, ...) in another
folder.


@setlocal

@ECHO OFF

REM get just file name. RadAsm3 passes complete path with non project files
REM ----------------------------
SET F=%~n1
REM ----------------------------

IF NOT EXIST %F%.cpp GOTO usage

REM I have this set in RadAsm3 which calls this bat file.
REM unComment so we can find SetEnv.cmd
REM SET PATH=C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\;%PATH%


IF [%2]==[] GOTO usage
IF [%3]==[] GOTO usage
SET BUILD=%4
IF [%BUILD%]==[] SET BUILD=Release


REM Set up the environment for compiling.
REM parameter 2 -> X86 or X64
REM parameter 3 -> con or gui or dll
REM parameter 4 -> Release or Debug


CALL SetEnv.cmd /%2 /%BUILD%


IF /I [%3] == [CON] (
  SET SUBSYS= /SUBSYSTEM:CONSOLE
  SET FTYPE="a Windows Console App"
)

IF /I [%3] == [GUI] (
  SET SUBSYS=/SUBSYSTEM:WINDOWS
  SET FTYPE="a Windows Gui App"
)

IF /I [%3] == [DLL] (
  SET SUBSYS=/DLL
  SET FTYPE="a Windows DLL"
)


REM --------------------------------------------------------------
REM always use the %F%.rc file in the Res Directory if it exists
REM this should handle both projects and individual files with resources



IF EXIST res\%F%.rc (
  ECHO Compiling resources.....
  cd res
  Rc %F%
  SET VRES=res\%F%.res
  cd ..
) ELSE (
  IF EXIST %F%.rc (
    ECHO Compiling resources.....
    Rc %F%
    SET VRES=%F%.res
  )
)

REM --------------------------------------------------------------
ECHO Compiling "%F%.cpp" To %FTYPE%
REM Note: no compiler/linker parameters
REM---------------------------------------------------------------
IF /I [%3]==[DLL] (
cl.exe /D_USRDLL /D_WINDLL "%F%.cpp" %VRES% /link /DLL /OUT:"%F%.dll"
) ELSE (
cl.exe  %F%.cpp /Fe%F%.EXE %WIN_VER% %VRES% %SUBSYSTEM% %5 %6 %7 %8
)

ECHO Finished!
IF EXIST "%F%.obj" del "%F%.obj"
IF EXIST "%F%.res" del "%F%.res"
GOTO done
:usage
ECHO **************************************************************
ECHO  Usage:  VC.BAT MainFile  [x86  x64] [con  gui  dll] extra files
ECHO  Note:   ExtraFiles can be .libs, .res , .obj
ECHO **************************************************************
:done
endlocal
exit



I am only going to show one scenerio here. A c++ app calling a stdcall function in a dll where
the dll does a callback to the app (a cdecl function)

The attachment contains three other ones.

C++ App calling a cdecl function in a dll and the dll calls back to a cdecl function
C++ App Calling a stdcall function in a dll and the dll calls back to a stdcall function
C++ App Calling a cdecl function in a dll and the dll calls back to a stdcall function

My Bc9 code that produces and compiles the c++ code
Dll

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'vc_ccb_sdll_32.bas
'------------------------------------------------------------------------------
'MyDllFunction is a stdcall function that calls a cdecl function in the caller
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

$DLL STDCALL
$CPP
$ONEXIT "cmd.exe /V:ON /K VC.BAT $FILE$ X86 dll Release"
  $TYPEDEF BOOL (*foo)(int,char*)
'==============================================================================
FUNCTION MyDllFunction(x$,fooptr as foo ) AS BOOL EXPORT
    DIM z$
    z$ = UCASE$(x$)
    IF fooptr(1, z$) = TRUE THEN
        MSGBOX "foo is true"
        FUNCTION = TRUE
    END IF
END FUNCTION
'==============================================================================


C++ Dll Code:

// *********************************************************************
// Created with Bc9 - BASIC To C/C++ Translator (V) 9.0.4.2 (2012/10/20)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C++ Compiler
//                           On MS Windows
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <wchar.h>      // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <winsock.h>    // Win32 Header File
#include <process.h>    // dos
#include <conio.h>      // dos
#include <direct.h>     // dos
#include <io.h>         // dos
#include <ctype.h>      // dos/linux
#include <fcntl.h>      // dos/linux
#include <math.h>       // dos/linux
#include <stdio.h>      // dos/linux
#include <string.h>     // dos/linux
#include <stddef.h>     // dos/linux
#include <stdlib.h>     // dos/linux
#include <setjmp.h>     // dos/linux
#include <time.h>       // dos/linux
#include <stdarg.h>     // dos/linux
#include <sys/types.h> 
#include <sys/stat.h>   


// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
  #define overloaded
  #define C_EXPORT EXTERN_C __declspec(dllexport)
  #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
  #define C_EXPORT __declspec(dllexport)
  #define C_IMPORT __declspec(dllimport)
#endif

// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
  #define atanl atan
  #define sinl  sin
  #define cosl  cos
  #define tanl  tan
  #define asinl asin
  #define acosl acos
  #define log10l log10
  #define logl   log
  #define _fcloseall fcloseall
#endif

// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
  // ===== Borland Libraries ==========
  #include <dos.h>
  #pragma comment(lib,"import32.lib")
  #pragma comment(lib,"cw32.lib")
  // ==================================
#endif

// Microsoft VC++
#ifndef DECLSPEC_UUID
  #if (_MSC_VER >= 1100) && defined ( __cplusplus )
    #define DECLSPEC_UUID(x)    __declspec(uuid(x))
  #else
    #define DECLSPEC_UUID(x)
  #endif
#endif

// *************************************************
// Tiny C support for LinkRes2Exe
#ifdef __TINYC__
  int dummy __attribute__ ((section(".rsrc")));
#endif
// *************************************************

#ifndef __cplusplus
  #error A C++ compiler is required
#endif
typedef BOOL (*foo)(int,char*);

// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#if !defined( __LCC__ )
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
#endif
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

char*   BCX_TmpStr(size_t,size_t= 128,int= 1);
char*   ucase (char*);
char*   _strupr_(char *);
char*   _strlwr_(char *);
// *************************************************
//          User Defined Types And Unions
// *************************************************


// *************************************************
//                System Variables
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *g_argv;
static int     g_argc;
static HINSTANCE BCX_hInstance;


// *************************************************
//               User Prototypes
// *************************************************

C_EXPORT BOOL __stdcall MyDllFunction (char*  ,foo);

// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
char *BCX_TmpStr (size_t Bites,size_t  iPad,int iAlloc)
{
  static int   StrCnt;
  static char *StrFunc[BCXTmpStrSize];
  StrCnt=(StrCnt + 1) & (BCXTmpStrSize-1);
  if(StrFunc[StrCnt]) {free (StrFunc[StrCnt]); StrFunc[StrCnt] = NULL;}
#if defined BCX_MAX_VAR_SIZE
  if(Bites*sizeof(char)>BCX_MAX_VAR_SIZE)
  {
  printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n",(int)(Bites*sizeof(char)),BCX_MAX_VAR_SIZE);
  abort();
  }
#endif
  if(iAlloc) StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
  return StrFunc[StrCnt];
}


char *ucase (char *S)
{
  register char *strtmp = BCX_TmpStr(strlen(S),128,1);
  return _strupr_(strcpy(strtmp,S));
}


char *_strupr_(char *string)
{
   char *s;

   if (string)
   {
      for(s = string; *s; ++s)
         *s = toupper(*s);
   }
   return string;
}

char *_strlwr_(char *string)
{
    char *s;

    if (string)
    {
       for (s = string; *s; ++s)
           *s = tolower(*s);
    }
    return string;
}



// ************************************
//       User Subs and Functions
// ************************************

C_EXPORT BOOL __stdcall MyDllFunction (char* x,foo  fooptr)
{
  static char    z[cSizeOfDefaultString];
  strcpy(z,ucase(x));
  if(fooptr(1,z)==true )
    {
      MessageBox (GetActiveWindow(),"foo is true","",0);
      return true;
    }
}


// *************************************************
//                  Main Program
// *************************************************


__declspec(dllexport) BOOL WINAPI DllMain (HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
BCX_hInstance = hInst;
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}


Code to test the dll
Bc9:

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'vc_test_ccb_sdll_32.bas
' call a stdcall dll function  with a cdecl callback
'dll -> vc_ccb_sdll_32.dll
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

$CPP
$ONEXIT "cmd.exe /V:ON /K VC.BAT $FILE$ X86 con Release vc_ccb_sdll_32.lib"

$TYPEDEF BOOL (*foo)(int,char*)

DECLARE FUNCTION MyDllFunction(A$,f As foo)AS BOOL

Dim rv As BOOL


rv = MyDllFunction ("little lamb", MyFoo)


PRINT "I'm Back and waiting"
PAUSE
'==============================================================================
'callback function called from ccb_sdll_32.dll
'------------------------------------------------------------------------------
FUNCTION MyFoo(a%, cc$) AS BOOL
    PRINT a%, " ", cc$
    FUNCTION = TRUE
END FUNCTION


C++

// *********************************************************************
// Created with Bc9 - BASIC To C/C++ Translator (V) 9.0.4.2 (2012/10/20)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C++ Compiler
//                           On MS Windows
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <wchar.h>      // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <winsock.h>    // Win32 Header File
#include <process.h>    // dos
#include <conio.h>      // dos
#include <direct.h>     // dos
#include <io.h>         // dos
#include <ctype.h>      // dos/linux
#include <fcntl.h>      // dos/linux
#include <math.h>       // dos/linux
#include <stdio.h>      // dos/linux
#include <string.h>     // dos/linux
#include <stddef.h>     // dos/linux
#include <stdlib.h>     // dos/linux
#include <setjmp.h>     // dos/linux
#include <time.h>       // dos/linux
#include <stdarg.h>     // dos/linux
#include <sys/types.h> 
#include <sys/stat.h>   


// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
  #define overloaded
  #define C_EXPORT EXTERN_C __declspec(dllexport)
  #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
  #define C_EXPORT __declspec(dllexport)
  #define C_IMPORT __declspec(dllimport)
#endif

// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
  #define atanl atan
  #define sinl  sin
  #define cosl  cos
  #define tanl  tan
  #define asinl asin
  #define acosl acos
  #define log10l log10
  #define logl   log
  #define _fcloseall fcloseall
#endif

// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
  // ===== Borland Libraries ==========
  #include <dos.h>
  #pragma comment(lib,"import32.lib")
  #pragma comment(lib,"cw32.lib")
  // ==================================
#endif

// Microsoft VC++
#ifndef DECLSPEC_UUID
  #if (_MSC_VER >= 1100) && defined ( __cplusplus )
    #define DECLSPEC_UUID(x)    __declspec(uuid(x))
  #else
    #define DECLSPEC_UUID(x)
  #endif
#endif

// *************************************************
// Tiny C support for LinkRes2Exe
#ifdef __TINYC__
  int dummy __attribute__ ((section(".rsrc")));
#endif
// *************************************************

#ifndef __cplusplus
  #error A C++ compiler is required
#endif
typedef BOOL (*foo)(int,char*);

// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#if !defined( __LCC__ )
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
#endif
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

void    Pause (void);
// *************************************************
//          User Defined Types And Unions
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *g_argv;
static int     g_argc;
static BOOL    rv;


// *************************************************
//               User Prototypes
// *************************************************

C_IMPORT BOOL   __stdcall MyDllFunction(char *,foo);
BOOL    MyFoo (int,char*);

// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

void Pause(void)
{
  printf("\n%s\n","Press any key to continue . . .");
  _getch();
}



// ************************************
//       User Subs and Functions
// ************************************

BOOL MyFoo (int a,char* cc)
{
  printf("% d%s%s\n",(int)a," ",cc);
  return true;
}


// *************************************************
//                  Main Program
// *************************************************

int main(int argc, char *argv[])
{
  g_argc = argc;
  g_argv = argv;
rv= MyDllFunction("little lamb", MyFoo);
printf("%s\n","I'm Back and waiting");
Pause();
  return 0;   /* End of main program */
}



James
Title: Re: My first steps with C++
Post by: Paul Squires on December 10, 2012, 08:36:37 PM
Quote from: Patrice Terrier on December 10, 2012, 06:55:11 PM
James--

Spend all the afternoon to patch VS2010 to the latest, and installing SDK 7.1 that failed 3 times before i could figure from Google what to do (had to uninstall first the redistributable package that was installed by another software before i could succeed with SDK 7.1, a real pain).

Anyway now i should be up and running, and this story is another good reason why i want to go full SDK to avoid the need to install any redistributable runtime.

...

Thanks Patrice! I tried to install 7.1 last week and ran into problems just like you did. I read your post today and then uninstalled the 2010 C++ redistributable packages. The SDK now installed perfectly.

:)

Title: Re: My first steps with C++
Post by: Larry Charlton on December 11, 2012, 06:13:51 AM
fwiw VS 2012 Express, supports 64bit out of the box now.
Title: Re: My first steps with C++
Post by: Patrice Terrier on December 11, 2012, 02:47:03 PM
James,

Thank you for the ZIP file.

For now, i don't want to be biaised anymore with exotics, and want to use only Visual Studio, because it is defacto the standard.

So far i have been able to create my first C Win32 DLL, and i was able to call it from a short PB test.exe.

My next step would be to create a 64-bit DLL, and call it from WinDev  8)

...
Title: Re: My first steps with C++
Post by: James C. Fuller on December 11, 2012, 08:01:28 PM
Quote from: Patrice Terrier on December 11, 2012, 02:47:03 PM
James,

Thank you for the ZIP file.

For now, i don't want to be biaised anymore with exotics, and want to use only Visual Studio, because it is defacto the standard.

So far i have been able to create my first C Win32 DLL, and i was able to call it from a short PB test.exe.

My next step would be to create a 64-bit DLL, and call it from WinDev  8)

...

Patrice,
  I thought you wanted to create MFC free SDK code?

Any way I was able to create a batch file to do the same using VS 2012 Express and the Win8 SDK on Windows 8.
You may not need the Win8 SDK as it does not have any compilers but as Larry pointed out VS 2012 will create 64bit apps/dlls.

James


@setlocal

@ECHO OFF
:: -----------------------------------------------------------------
:: Batch file to compile c++ applications using Visual Studio 2012
:: and the Win8 sdk

REM get just file name. RadAsm3 passes complete path with non project files
REM ----------------------------
SET F=%~n1
REM ----------------------------

IF NOT EXIST %F%.cpp GOTO usage


IF [%2]==[] GOTO usage
IF [%3]==[] GOTO usage
REM SET BUILD=%4
REM IF [%BUILD%]==[] SET BUILD=Release


REM Set up the environment for compiling.
REM parameter 2 -> x86 or x86_amd64
REM parameter 3 -> con or gui or dll

CALL "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" %2

IF /I [%3] == [CON] (
  SET SUBSYS= /SUBSYSTEM:CONSOLE
  SET FTYPE="Windows Console App"
)

IF /I [%3] == [GUI] (
  SET SUBSYS=/SUBSYSTEM:WINDOWS
  SET FTYPE="Windows Gui App"
)

IF /I [%3] == [DLL] (
  SET SUBSYS=/DLL
  SET FTYPE="a Windows DLL"
)


REM --------------------------------------------------------------
REM always use the %F%.rc file in the Res Directory if it exists
REM this should handle both projects and individual files with resources



IF EXIST res\%F%.rc (
  ECHO Compiling resources.....
  cd res
  Rc %F%
  SET VRES=res\%F%.res
  cd ..
) ELSE (
  IF EXIST %F%.rc (
    ECHO Compiling resources.....
    Rc %F%
    SET VRES=%F%.res
  )
)

REM --------------------------------------------------------------
ECHO Compiling "%F%.cpp" To %FTYPE%
IF /I [%3]==[DLL] (
cl.exe /D_USRDLL /D_WINDLL "%F%.cpp" %VRES% /link /DLL /OUT:"%F%.dll"
) ELSE (
cl.exe  %F%.cpp /Fe%F%.EXE %WIN_VER% %VRES% %SUBSYSTEM% %5 %6 %7 %8
)

ECHO Finished!
IF EXIST "%F%.obj" del "%F%.obj"
IF EXIST "%F%.res" del "%F%.res"
GOTO done
:usage
ECHO **************************************************************
ECHO  Usage:  VC.BAT MainFile  [x86  x64] [con  gui  dll] extra files
ECHO  Note:   ExtraFiles can be .libs, .res , .obj
ECHO **************************************************************
:done
endlocal
exit



Title: Re: My first steps with C++
Post by: Patrice Terrier on December 11, 2012, 08:19:18 PM
James

I don't want to wrap my GDImage/WinLIFT API into Microsoft Foundation Class (MFC), for now i want to keep it as low level flat API (32/64-bit).

...
Title: Re: My first steps with C++
Post by: Patrice Terrier on December 12, 2012, 11:59:20 AM
Written my first VS2010 64-bit flat API DLL, using WinDev to test it.

So far the 64-bit version is only 14% larger than the 32-bit, but the test DLL is very basic, and does only simple long addition returning the result to the calling application.

...
Title: Re: My first steps with C++
Post by: Patrice Terrier on September 25, 2013, 03:46:21 PM
I have been able to match successfully 32 and 64-bit code inside of a same project, using private messages based on the RegisterWindowMessage API to communicate between the different modules in real time.

:)
Title: Re: My first steps with C++
Post by: Anand Kumar on September 25, 2013, 05:45:02 PM
Patrice,

You might consider using Pipes.  The trouble with messages is that if you would like to send text or structures from 32 to 64 bit then there might be access issues.  Pipes are far easier to work with in such situations.

Title: Re: My first steps with C++
Post by: Patrice Terrier on September 25, 2013, 09:27:16 PM
Anand

I am already sending all my data as byte, thus i don't know if that would make a big difference.
Socket or memory mapped file could be used as well, but using private message is so easy to use once you know the handle of the target window.

For those interrested here is a good link on this topic:
http://www.codeproject.com/Articles/13724/Windows-IPC (http://www.codeproject.com/Articles/13724/Windows-IPC)
Title: Re: My first steps with C++
Post by: Anand Kumar on September 26, 2013, 01:56:39 AM
Patrice,

The choice of pipes or any other IPC mechanisms depends on the amount of data that you would like to transfer and  the size of the data chunks that you can send across in a single transmission.  Moreover, messages can be intercepted.

With pipes, two way communication is possible and the amount of data that you can send is quite reasonable (send the length of the data first and then the content). You can include authentication mechanisms to validate the sessions (trusted connectivity). 

Anand
Title: What do you think of VS2013
Post by: Patrice Terrier on October 26, 2013, 02:59:19 PM
Currently i am still using C++ from VS2010 Pro, and i would like to know if i should move to VS2013.

What do you think are the most significative new features ?
Title: Re: What do you think of VS2013
Post by: Jim Dunn on October 26, 2013, 05:15:31 PM
Quote from: Patrice Terrier on October 26, 2013, 02:59:19 PM
Currently i am still using C++ from VS2010 Pro, and i would like to know if i should move to VS2013.

What do you think are the most significative new features ?

http://www.hanselman.com/blog/SCREENCASTSWhatsNewInVisualStudio2013LearnOverLunch.aspx
Title: Re: My first steps with C++
Post by: Patrice Terrier on October 26, 2013, 06:10:44 PM
Jim--

Thanks, but the link refers mostly to web programming.
I want to know what is new for the core C/C++ 64-bit compiler (because there are many parts of VS that i do not care about for the moment).
Title: Re: My first steps with C++
Post by: Brice Manuel on October 26, 2013, 07:01:57 PM
There is a fairly detailed list here which includes info on the compiler:

http://blogs.msdn.com/b/vcblog/archive/2013/06/27/what-s-new-for-visual-c-developers-in-vs2013-preview.aspx
Title: Re: My first steps with C++
Post by: Patrice Terrier on October 26, 2013, 07:38:05 PM
Brice--

Thank you.

I will wait to upgrade until the official release.

Title: Re: My first steps with C++
Post by: James C. Fuller on October 26, 2013, 07:57:27 PM
Patrice,
  Official release??
I think it has been released officially.

http://www.microsoft.com/visualstudio/eng/downloads#d-2013-editions

James
Title: Re: My first steps with C++
Post by: Mike Stefanik on October 26, 2013, 08:01:04 PM
VS2013 was released last week, but you have to be an MSDN subscriber to download it. The official launch date is in a few weeks, on November 13th. If you do plan on upgrading, one thing that you should keep in mind is that you plan on continuing to support Windows XP, you need to make sure that your projects use the right toolset. In your project properties (General section) you'll see a field named Project Toolset. In VS2012 and VS2013, you'll see something like the following:

Visual Studio 2012 (v110)
Visual Studio 2012 - Windows XP (v110_xp)
Visual Studio 2010 (v100)
Visual Studio 2008 (v90)

If you load up your existing VS2010 projects, the toolset should remain "Visual Studio 2010 (v100)" and that's fine. But if you create new projects, or want to take advantage of new compiler features, you want to make sure that you use the "Visual Studio 2012 - Windows XP (v110_xp)" toolset. If your project uses the "Visual Studio 2012 (v110)" toolset, your DLLs will not load on Windows XP systems because the libraries that they link with will make calls to kernel functions that only exist in Windows Vista and later platforms.

Edit: It looks like you can download VS2013 to try it out, but you can't actually purchase a license yet unless you buy an MSDN subscription. If you go to the Microsoft Store to buy a Visual Studio license, it's still for VS2012.
Title: Re: My first steps with C++
Post by: Patrice Terrier on October 26, 2013, 08:19:31 PM
QuoteIf you go to the Microsoft Store to buy a Visual Studio license, it's still for VS2012.
Yes, same here, the official VS2013 Pro is not yet available without a MSDN subscription, have to wait the begining of 2014.

By the way, i have another question, related to Unicode.

All my GDImage 64-bit is now unicode, however when creating bitmapped font for OpenGL i still need to use ANSI char.
Thus my question is what is the best method to convert from WCHAR to char, currently i am using wcstombs_s is that the best one?
Title: Re: My first steps with C++
Post by: Mike Stefanik on October 26, 2013, 08:39:25 PM
Quote from: Patrice Terrier on October 26, 2013, 08:19:31 PM
Thus my question is what is the best method to convert from WCHAR to char, currently i am using wcstombs_s is that the best one?

That's fine. Internally, the CRT function calls _wcstombs_l_helper which is really just a wrapper around the WideCharToMultiByte function, along with some additional checks for the "C" locale and whatever the current locale codepage is.
Title: Re: My first steps with C++
Post by: Jim Dunn on October 27, 2013, 06:30:46 PM
Quote... you plan on continuing to support Windows XP, you need to ...

I know I *always* get shot down when I mention this, but XP is going end of like in April 2014.  I'm sure there will be a lot of people try to keep using it, but without security updates, it would not be wise.

Ok, go ahead... line up and tell me about all the clients you have that are still using MSDOS.
Title: Re: My first steps with C++
Post by: Mike Stefanik on October 27, 2013, 06:56:54 PM
Quote from: Jim Dunn on October 27, 2013, 06:30:46 PM
I know I *always* get shot down when I mention this, but XP is going end of like in April 2014.  I'm sure there will be a lot of people try to keep using it, but without security updates, it would not be wise.

That's generally the case, but not entirely accurate. Microsoft has left the door open that they may issue hotfixes for what they described as "very critical security flaws", but aside from that, after April 8th, 2014 they will only be providing updates for corporate customers with custom support plans (typically those are support agreements that a company has with Microsoft for their fleet of PCs, where they are charged a certain amount per PC, per year with the costs increasing for each year after the product has reached its end-of-life).

And just so folks are aware, all things XP will not be going dark in April. Windows Update will continue to work, and you'll continue to be able to install and activate XP on new systems. It's just that there won't be any new updates published, normally. I suspect that if there was some particularly nasty zero-day vulnerability that shows up, Microsoft might feel compelled to push out a security update for XP, but you can't count on it.

I know when we've talked to our customers, a lot of them plan on continuing to support XP beyond it's end-of-life and that means we will need to continue to support them. I'm sure it will reach a point where Windows XP becomes like Windows 2000, but with still over 30% marketshare, XP will continue to be around for a while. My concern is with malware that is being kept on the shelf right now because it exploits an as-of-yet undiscovered flaw in XP and they only want to deploy it after April, 2014 for maximum effect.

Title: Re: My first steps with C++
Post by: Jim Dunn on October 27, 2013, 10:19:38 PM
Mike, thanks for your reply, well said, and... thanks for going easy on me.
Title: Problem allocating dynamic memory in a C++ DLL
Post by: Patrice Terrier on October 28, 2013, 11:01:33 AM
I have been faced with a nasty problem while allocating dynamic memory from inside of a DLL.

I am using this to allocate the memory inside of the DLL
BYTE* lpArray = (BYTE*) malloc(Xin * Yin * 4);
then i return the BYTE* to be used outside of the DLL, within the calling EXE,
and after i am done with it, i am freeing back the memory using this:
free (lpArray);

And bim, bam, badaboum, i am throwing up an exception error as soon as free.c is performing
        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0)
        {
            errno = _get_errno_from_oserr(GetLastError());
        }


I have never been faced with this problem with PB (using REDIM to allocate dynamic memory), thus i was taken by surprise by that one.

I have found this article: http://msdn.microsoft.com/en-us/library/ms235460%28v=vs.110%29.aspx
that seems to match this case.
Title: Re: My first steps with C++
Post by: James C. Fuller on October 28, 2013, 03:45:10 PM
Patrice,
It appears you should be using free as you use malloc to allocate the memory?

James

Title: Re: My first steps with C++
Post by: Patrice Terrier on October 28, 2013, 04:04:00 PM
James--

Yes, I am using free already, what i have posted is the debug code that shows, that the matching C code that does the work under the hood at the time we use free, is causing the havoc.

I know how to solve the problem (allocating memory in the calling application, rather than in the DLL), but it is just to warn those who may allocate dynamic memory from within a DLL, especially when using the "Multithread /MT" flag option with another DLL or main application using a different setting.
Title: Re: My first steps with C++
Post by: Mike Stefanik on October 28, 2013, 05:16:24 PM
You should never use malloc or new to allocate memory from within a DLL and then free that memory in an external function (i.e.: in the executable or another DLL). If you want to allocate a block of memory that will be released by another function in your executable, then you want to use HeapAlloc:


LPBYTE lpArray = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (Xin * Yin * 4));


And you would free that memory by calling:


HeapFree(GetProcessHeap(), 0, lpArray);


Another option would be to provide your own function that explicitly frees the memory with your DLL. The reason is that when you statically link to the CRT, your DLL has its own instance of the runtime heap which is different than the heap that is allocated for your executable.
Title: Re: My first steps with C++
Post by: Patrice Terrier on October 28, 2013, 05:27:54 PM
I thougth that C++ malloc was an encapsulation for HeapAlloc, my mistake.

Thanks Mike!
Title: Re: My first steps with C++
Post by: Mike Stefanik on October 28, 2013, 05:47:14 PM
Both new and malloc do eventually call HeapAlloc, but the runtime allocates it's own heap rather than using the default process heap. It also does things a bit differently if you have a debug build to make it easier for it to track allocations, etc. Note that this also impacts allocations that go the other way (i.e.: your DLL should never attempt to free a block of memory that has been allocated by your main executable using malloc or new).
Title: Re: My first steps with C++
Post by: Patrice Terrier on October 28, 2013, 05:57:14 PM
Mike--

QuoteActually, malloc() (and other C runtime heap functions) are module dependant, which means that if you call malloc() in code from one module (i.e. a DLL), then you should call free() within code of the same module or you could suffer some pretty bad heap corruption (and this has been well documented). Using HeapAlloc() with GetProcessHeap() instead of malloc(), including overloading new and delete operators to make use of such, allow you to pass dynamically allocated objects between modules and not have to worry about memory corruption if memory is allocated in code of one module and freed in code of another module once the pointer to a block of memory has been passed across to an external module.

I found it there: http://stackoverflow.com/questions/8224347/malloc-vs-heapalloc

a confirmation of your previous post, thanks!
Title: After using C++ for several monthes
Post by: Patrice Terrier on December 05, 2013, 05:48:12 PM
After using C++ for several monthes now, i can share this feedback with you...

Once the initial learning phase is over:
the first thing that really make a big difference is that you don't have to mess with includes and headers anymore,
second you can type in ALL the Windows API without restriction,
third you can use the latest technology and produce 32-bit and 64-bit from the same source code.

Switching to UNICODE is the thing that you must do as soon as possible,
then learn how to use VECTOR (dynamic array replacement, and much more),
and move to wstring (just as easy as BASIC strings).

Then try to keep as close as possible to the syntax indentation you are using in PB, to ease the reading of the source code.
Use Hungarian notation to easily detect the variable type.

Learn how to cast one variable type to another, because C++ is using strong typing.
ALWAYS assign your variables, your arrays, your type structures, before using them.

Be careful on the / (divide) optimization, always use (float) to avoid rounding errors.

Never try to compare strings with == (because C++ does a pointer comparison), instead use the string.compare() function.

After a while, you will realize that for a SDK programmer, C++ is not that harder to use than PB, as long as you stay away of the C++ encapsulation, that is just another kind of DDT. :)

...


Title: 64-bit version of BASS.dll ?
Post by: Patrice Terrier on December 11, 2013, 10:36:25 AM
Does anyone has used the 64-bit version of BASS.dll ?

...
Title: Re: 64-bit version of BASS.dll ?
Post by: Brice Manuel on December 12, 2013, 02:34:03 PM
Quote from: Patrice Terrier on December 11, 2013, 10:36:25 AM
Does anyone has used the 64-bit version of BASS.dll ?
No, but I was planning to very soon.