ObjReader Community

Tips & Tricks => Take the control of your window => Topic started by: Patrice Terrier on February 10, 2020, 10:07:46 am

Title: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on February 10, 2020, 10:07:46 am
Since José Roca has moved to FreeBasic, and PowerBASIC has gone to oblivion.
I took the decison to remove all my contributions from my "consultant section" on "José Roca's forum" (new name "Theo's forum").

The only thing i have moved there, is the Take the control of your window (http://www.objreader.com/index.php?board=11.0) thread.
But of course if you need anything specific about my previous PB's contributions, you can ask here, and i shall try from my best to help you.
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on February 12, 2020, 09:19:37 am
I am looking for a {young} SDK programmer that could take on my work with GDImage and WinLIFT.

Please contact me first by PM, and not from this thread.
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 15, 2020, 12:35:03 am
Hey,

I won't pretend to be a {young} SDK programmer that could take on your work.  :-)

-

Very, very long time ago, a friend told me, "Go C++".
It was a pretty good advise. I did not follow...
I had too much fun with PowerBASIC.

Today, I feel like I want a new toy.
I've been playing with PureBASIC, FreeBASIC, LCC, Pelles C, MinGW (CodeBlock & Dev-Cpp as IDE).

I wanted to avoid the multi giga-bytes Visual Studio,
I wanted something compact.

Today, I give up, if you can't beat them, join them...
I'll go with Bill.
I remember you say that your C stuff was smaller and faster than before.
That this compiler was good...
I must say, it is!
No more code to convert from C++ to something else.
Direct copy and paste!
Lots of tutorials, lots of forums, a direct fit.
A real fine IDE! (I will try Visual Studio Code, but later)

Life is easy!
Well, it will be... still much to learn.

Beside what you got here, if I remember well,
you had an article describing how to compile compact code with no C DLL dependency.
And functions to mimic PowerBASIC ones.
If it is still available, I'd like to have...

BSTR was easy to work with, am I right to say that using a mix of wchar_t, char_t, and std::wstring is a good approach for a clean future?

You know what! In a sense, the absence of PB64 was a good thing for you,
you got much more than 64 bit, you got a new universe!

I like those three...
https://www.learncpp.com/
https://en.cppreference.com/w/
http://www.cplusplus.com

Salut et merci,
Pierre
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 15, 2020, 05:38:06 am
For your functions, I'm almost sure it was those...
Do you think it is fairly complete?
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 15, 2020, 11:04:28 am
Pierre

I shall be very pleased to help you.
And for those mastering the low level SDK API (like yourself), it is fairly easy to move from PB to plain C/C++.

First thing is to select the best compiler for the OS platform.
On Windows, there is no dispute, use the same compiler that the one used to write the OS itself, aka: Visual Studio.

Visual Studio Community is free, and always uptodate!
I have 2010, 2013, 2015, 2017, 2019, and i keep using 2010 to produce my 64-bit DLLs (smaller code).

When I started to convert WinLIFT and GDImage from PB, my first goal was to retrieve the same basic functions i was familiar with, until i get comfortable with their native C/C++ counterpart.

I have posted a bunch of source code here, to learn from.

And the Tools.h include, has most of the API i am using with all my projects.

You can start with the Address book project that is a small PB's translation, resulting in a standalone native 64-bit application of only 30 Kb: http://www.objreader.com/index.php?topic=111.msg998#msg998


Once you have installed Visual Studio, then i could tell you what settings to use to produce small 64-bit standalones,
like in this thread: http://www.objreader.com/index.php?topic=91.msg618#msg618

 
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 15, 2020, 09:00:24 pm
Great,

What I got so far...
Visual Studio Community 2019.
  Visual Studio Intellicode.
  SDK 10 (10.0.17763.0) is installed
  Help Viewer
(Visual studio Code editor, I will try it much later, first I got to know Visual Studio)

If you know of a good text macro tool, please tell, those I tried are "couci-couça" for my taste...
Aka... "Text Macro for Visual Studio", "Macro for Visual Studio", "Visual Commander".
Also if you know some "must have" add on.

Config I will try to keep...
Project-name / Properties / Configuration Properties / C++ / Language : Disable Language Extension = No
Project-name / Properties / Configuration Properties / C++ / Language : C++ Language standard      = ISO C++17 Standard (/std:c++17)
Project-name / Properties / Configuration Properties / C++ / General: Warning Level                = Level4 (/W4) [or EnableAllWarnings (WALL)]

Thanks for the vs2010 smaller code hint, I'll remember this.
I see Tool.h is in the address book, good for me. I will read...

I'm not sure if it is going to last,
but this is the first time I really and seriously consider
making PowerBASIC a second alternative compiler...

All I got to do is work, work, work, and work...

Thank you Patrice, I appreciate what you do.

Pierre
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 15, 2020, 09:24:26 pm
The concept of Macro is much more complex in VS than in PB,  here is an example:

The ObjReader DOLIGHTON(n,x,y,z) macro
Code: [Select]
#define DOLIGHTON(n,x,y,z) \
    gP.bIsLight##n##_On = !gP.bIsLight##n##_On; \
    SetSwitch(ID_ONOFF##n##, gP.bIsLight##n##_On); \
    if (gP.bIsLight##n##_On) { \
        gP.nLightFlags |= (1 << (n)); /* bin 0001, 0010, 0100, or 1000 ==> dec 1, 2, 4, or 8 ==> (1 << (n)) */\
        if (gP.bIsLight##x##_On && gP.bIsLight##y##_On && gP.bIsLight##z##_On) { \
            gP.bMultiLight = TRUE; \
            gP.nLightFlags = 15; /* bin 1111 ==> dec 15 always */ \
            CheckMenuItem(gP.hSubMenu, MENU_BRIGHT_LIGHT, MF_CHECKED); \
        } \
    } \
    else { \
        gP.nLightFlags &= (15 ^ (1 << (n))); /* bin 1110, 1101, 1011, or 0111 ==> dec 14, 13, 11, or 7 ==> (15 ^ (1 << (n))) */ \
        if (gP.bMultiLight) { \
            gP.bMultiLight = FALSE; \
            CheckMenuItem(gP.hSubMenu, MENU_BRIGHT_LIGHT, MF_UNCHECKED); \
        } \
    }

But to say the truth, i prefer to use functions rather than macro, except for simple like these:
Code: [Select]
#define LOINT(a) ((SHORT)(a))
#define HIINT(a) ((SHORT)(((DWORD)(a) >> 16) & 0xFFFF))
#define LOWORD(a) ((WORD)(a))
#define HIWORD(a) ((WORD)(((DWORD)(a) >> 16) & 0xFFFF))
#define MAKLNG(a, b) ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))
#define UBOUND(T) ((long) T.size())
#define strSize(s) ( sizeof(s) / sizeof(s[0]) )

About must have, i would recommend WinMerge to detect for code changes.
https://winmerge.org/?lang=en

Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 15, 2020, 10:41:37 pm
Thanks, I already like and use WinMerge.

Also thank for the macro, I will study...
Still, I was thinking of an "editor text macro",
aka I type {Ctrl-Shift-T] in the editor part of VS with the [T] macro will write "SetWindowTextW(hwnd, L"Caption text"); at caret position.

Here is one of the things I've done so far...
Do not hesitate to tell if you see big No! No!
Code: [Select]
#include <windows.h>   
#include <commctrl.h>
#include <richedit.h>
#include <ntsecAPI.h>
#include <shellapi.h>
#include <wininet.h>
#include "main.h"

static LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
HFONT MakeFontEx(LPCWSTR, int, int, DWORD, DWORD);

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

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, WCHAR* pszCmdLine, int nCmdShow)
{
    HMODULE hRichEditLib = LoadLibraryW(L"MsftEdit.dll");  /* Load RichEdit "RichEdit50W" v4.1 */

    // Register the main window class
    WNDCLASSEX WinClass;
    WinClass.cbSize        = sizeof(WNDCLASSEX);
    WinClass.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
    WinClass.lpfnWndProc   = MainWndProc;
    WinClass.cbClsExtra    = 0;
    WinClass.cbWndExtra    = 0;
    WinClass.hInstance     = hInstance;
    WinClass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_ICO_MAIN));
    WinClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WinClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    WinClass.lpszMenuName  = 0;
    WinClass.lpszClassName = L"SimpleClass";
    WinClass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_ICO_MAIN));
   
    if (RegisterClassEx(&WinClass))
    {
        HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                                   L"SimpleClass",
                                   L"RichEdit",
                                   WS_OVERLAPPEDWINDOW,
                                   (GetSystemMetrics(SM_CXSCREEN) - 500) / 2, //Center window on desktop
                                   (GetSystemMetrics(SM_CYSCREEN) - 300) / 2, //Center window on desktop
                                   500,
                                   300,
                                   NULL,
                                   NULL,
                                   hInstance,
                                   0);

        // Show and paint the main window
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);

        // Pump messages until we are done
        MSG msg = {0,0,0,0,0,0,0};
        while (GetMessage(&msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        // Return msg.wParam;
    }
    FreeLibrary(hRichEditLib);
    return(0);
}

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

static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    wchar_t pURL[INTERNET_MAX_URL_LENGTH];
    CREATESTRUCT* pCreateStructure;
    ENLINK* param = (ENLINK*)lParam;

    switch (msg)
    {
    case WM_CREATE:
        pCreateStructure = (LPCREATESTRUCT)lParam; //Get instance from wWinMain
        static HINSTANCE hInstance;
        hInstance = pCreateStructure->hInstance;

        #ifdef _WIN64
        SetWindowText(hwnd, L"Simple app - 64bit");
        #else
        SetWindowText(hwnd, L"Simple app - 32bit");
        #endif

        RECT rc;
        GetClientRect(hwnd, &rc); //Get client rectangle

        //Create a richedit control
        static HWND hEdit;
        hEdit = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_RIGHTSCROLLBAR, L"RichEdit50W", L"",
            WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL |
            ES_WANTRETURN | ES_SAVESEL | ES_NOHIDESEL | WS_VSCROLL | WS_TABSTOP,
            2, 2, rc.right - 4, rc.bottom - 4,
            hwnd, NULL, hInstance, NULL);
       
        //URL detection
        SendMessage(hEdit, EM_AUTOURLDETECT, TRUE, 0);
        SendMessage(hEdit, EM_SETEVENTMASK, 0, ENM_LINK | ENM_PROTECTED);
       
        //Create a font
        static HFONT hFont;
        hFont = (HFONT)MakeFontEx(L"Segoe UI", 12, FW_NORMAL, FALSE, FALSE); //Create desired font
        SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, TRUE);

        SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)
            TEXT("\n C++ RichEdit -  Visual Studio 2019 !\n\n"
                " http://www.objreader.com/index.php?topic=319.0\n"
                " {Double click to go using default browser...}")); //Set text

        //Set control background color
        SendMessage(hEdit, EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, 0); //Extend background color
        SendMessage(hEdit, EM_SETBKGNDCOLOR, 0, RGB(200, 200, 200)); //Set background color

        //Set selection fore and back color
        CHARFORMAT2 ChrFormat;
        ChrFormat.cbSize      = sizeof(CHARFORMAT2);
        ChrFormat.dwEffects   = 0;
        ChrFormat.dwMask      = CFM_COLOR | CFM_BACKCOLOR;  //Flag for fore and back color
        ChrFormat.crTextColor = RGB(200, 0, 255);           //Fore color
        ChrFormat.crBackColor = RGB(255, 255, 0);           //Back color
        SendMessage(hEdit, EM_SETSEL, 17, 36);              // Select some text
        SendMessage(hEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&ChrFormat); //Set selection fore and back color
        SendMessage(hEdit, EM_SETSEL, -1, -1); //Remove selection by moving caret to the end
        SetFocus(hEdit); //Set focus
        break;

    case WM_NOTIFY:
        if ((param)->nmhdr.hwndFrom == hEdit) //Only hEdit
        {
            if ((param)->nmhdr.code == EN_LINK) //If we got EN_LINK code
            {
                if ((param)->msg == WM_LBUTTONDBLCLK) //If it is a double click
                {
                    DWORD UrlLen = ((param)->chrg.cpMax - (param)->chrg.cpMin + 2); //Get lenght of URL
                    TEXTRANGE TxtRange;
                    TxtRange.chrg = (param)->chrg; //Copy text range
                    TxtRange.lpstrText = pURL;  //Point to URL
                    SendMessage(hEdit, EM_GETTEXTRANGE, 0, (LPARAM)&TxtRange); //Get the URL text
                    HINSTANCE result;
                    result = ShellExecuteW(HWND_DESKTOP, L"open", pURL, L"", L"", SW_SHOW); //Open the URL using default browser.
                    PostMessage(hEdit, EM_SETSEL, (param)->chrg.cpMin, (param)->chrg.cpMin); //Remove selection
                }
            }
            return FALSE;
        }
        break;

    case WM_SIZE:
        if (wParam != SIZE_MINIMIZED)
        {
            MoveWindow(hEdit, 2, 2, LOWORD(lParam) - 4, HIWORD(lParam) - 4, TRUE); //Resize the richedit control
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0); //Say bye!
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
        break;
    }
}

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

bool CALLBACK MakeFontExEnumCharSet(LPLOGFONT elf, LPNEWTEXTMETRIC ntm, DWORD FontType, BYTE *CharSet)
{
    //Get type of character set - ansi, symbol. A must for some fonts.
    *CharSet = elf->lfCharSet;
    //UNREFERENCED_PARAMETER( lplf );
    return FALSE;
}

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

HFONT MakeFontEx(LPCWSTR wFontName, int PointSize, int fBold, DWORD fItalic, DWORD fUnderline)
{
    HDC hDC = GetDC(HWND_DESKTOP);
    DWORD CyPixels = GetDeviceCaps(hDC, LOGPIXELSY);
    //EnumFontFamilies(hDC, wFontName, &MakeFontExEnumCharSet, CharSet);
    BYTE CharSet = 0;
    EnumFontFamilies(hDC, wFontName, (FONTENUMPROC) &MakeFontExEnumCharSet, (LPARAM) &CharSet);
    //EnumFontFamilies(hDC, wFontName, (FONTENUMPROC) 0, (LPARAM) CharSet);
    ReleaseDC(HWND_DESKTOP, hDC);
    PointSize = 0 - (PointSize * CyPixels) / 72;

    HFONT font;
    font = CreateFont(PointSize, 0, //Height, width(default=0)
        0, 0,         //Escapement(angle), orientation
        fBold,        //Weight (%FW_DONTCARE = 0, %FW_NORMAL = 400, %FW_BOLD = 700)
        fItalic,      //Italic
        fUnderline,   //Underline
        FALSE,        //StrikeThru
        CharSet, OUT_TT_PRECIS,
        CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
        FF_DONTCARE, wFontName);
    return font;

}

//****************************************************************************
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 16, 2020, 11:52:03 am
Pierre

I have revisited your project to match my own programming style, based on a specific use of { } to ease translation from one language to another.

For example this PB code
if (condition) then
else
end if

becomes in C

if (condition) {
} else {
}

This allows me to perform easy search and replace
"then" --> "{"
"end if" --> "}"
"else" --> "} else {"

I have attached the code with my changes, and the project settings to produce a 89 Kb bare bone 64-bit standalone (no runtime).

Use WinMerge to see all my changes ;)

...
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 16, 2020, 02:05:59 pm
Great!

I got a many errors at compilation try with the reworked code of mine you did and also if I try the address book.

It's no big deal, surely some environments stuff and different version of VS.

So far, I must say I'm pretty pleased with VS.
Funny thing, I got the feeling I work with "PDS 7.1 Pro".
Started with Bill, ending with Bill... 

Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 16, 2020, 02:17:13 pm
I did send you the full environment, i am using 64-bit UNICODE FastCall (because of 64-bit).

Microsoft Visual Studio Community 2019
Version 16.6.2
VisualStudio.16.Release/16.6.2+30204.135
Microsoft .NET Framework
Version 4.8.03752

Installed Version: Community

Visual C++ 2019   00435-60000-00000-AA104
Microsoft Visual C++ 2019

ASP.NET and Web Tools 2019   16.6.948.25768
ASP.NET and Web Tools 2019

Azure App Service Tools v3.0.0   16.6.948.25768
Azure App Service Tools v3.0.0

C# Tools   3.6.0-4.20251.5+910223b64f108fcf039012e0849befb46ace6e66
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

IntelliCode Extension   1.0
IntelliCode Visual Studio Extension Detailed Info

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual C++ Wizards   1.0
Microsoft Visual C++ Wizards

Microsoft Visual Studio VC Package   1.0
Microsoft Visual Studio VC Package

NuGet Package Manager   5.6.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

ProjectServicesPackage Extension   1.0
ProjectServicesPackage Visual Studio Extension Detailed Info

Test Adapter for Boost.Test   1.0
Enables Visual Studio's testing tools with unit tests written for Boost.Test.  The use terms and Third Party Notices are available in the extension installation directory.

Test Adapter for Google Test   1.0
Enables Visual Studio's testing tools with unit tests written for Google Test.  The use terms and Third Party Notices are available in the extension installation directory.

TypeScript Tools   16.0.20417.2002
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   3.6.0-4.20251.5+910223b64f108fcf039012e0849befb46ace6e66
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Tools for CMake   1.0
Visual Studio Tools for CMake
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 16, 2020, 02:19:46 pm
I am currently installing VS 2019 community version 16.6.4

What you can do, is to send me a project that works by you, in order to let me check the settings you are using.

Because i don't care about 32-bit anymore, all my projects are setup for 64-bit UNICODE.
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 17, 2020, 02:11:20 am
Here it is the 7zipped folder, my environment is in  "~LaConfigDePierre.txt".

I guess there is a lot of fun in front of me, I like! :-)

Thanks for the help...

Pierre



 
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 17, 2020, 10:40:11 am
From your config:

You are still using x86 (32-bit) rather than x64 (64-bit),
and the project is in debug mode rather than in release mode.

That means, that your settings and mine are targeting two different platforms
You are using
Configutation, Release Platform: Win32 instead of x64

In Code Generation -> Runtime Library: Multi-threaded Debug DLL (/MDd) (that is a NoNo in release mode)
You should use instead Multi-threaded (/MT)

In your 'MainWndProc': not all control paths return a value
(this has been fixed on the version i sent you yesterday)

When using the x64 mode, the release folder is full of unwanted extra files because you are using the default settings, and thus the size of the resulting  EXE file is 106 Kb, while mine is 89 Kb with more functions.

I shall post a screen shot collection of the project properties i am using myself, to show you how to produce smaller code size.
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 17, 2020, 02:44:55 pm
Using several .ico files in your resource, enlarge the size of the resulting binary (to really see the size of the resulting binary i have removed all of them).
Using CS_OWNDC, should be limited to intensive graphic application.
You should check if your class doesn't exist already before creating a new one.
Give a look at the source code i wrote in the Pierre project, because i took the time to write it for you as a guidance.
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 18, 2020, 05:13:22 am
About x86/debug, agreed, I forgot to set x64/release after some manipulations.
Figured out how to set "Preprocessor Definitions"
CS_OWNDC removed.
All settings are now as you proposed.
All works fine...
This give me a nice configuration to start with.
Yes, I will give a look at the Pierre project again, now I am able to compile it...

I lost a lot of time in some code earlier because the lack of zero initialization...
The more you pay for an error, the more you remember not to do it again...

Now I'm going to play with RtlIntegerToUnicodeString();
The fun is not over yet!

Thank for your suggestions...





Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 18, 2020, 09:41:06 am
It's a start, a little one...
Code: [Select]
#include <windows.h>
#include <iostream>
#include <ntsecAPI.h> //"PUNICODE_STRING"
using namespace std;

typedef int(__cdecl* RtlIntegerToUnicodeString)(ULONG, ULONG, PUNICODE_STRING);
const ULONG STATUS_SUCCESS = 0;

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

std::wstring  uLongToString(ULONG dwValue, ULONG dwBase) {
    // Base: 2 binary, 8 octal, 10 decimal, 16 hexadecimal

    HMODULE hLib = LoadLibrary(L"NTDLL.DLL");
    if (hLib != NULL)
    {
        RtlIntegerToUnicodeString pProc = (RtlIntegerToUnicodeString) GetProcAddress(hLib, "RtlIntegerToUnicodeString");
        if (pProc != NULL)
        {
            UNICODE_STRING UnicodeString;
            wchar_t wBuffer[33];        //Longuest binary DWORD will be 32 characters
            UnicodeString.Buffer        = wBuffer;
            UnicodeString.Length        = 32;
            UnicodeString.MaximumLength = 32;

            NTSTATUS RetVal = (pProc) (dwValue, dwBase, &UnicodeString);
            if (STATUS_SUCCESS == RetVal) {
                std::wstring wString = wBuffer;
                return wString;
            }
        }
        FreeLibrary(hLib);
    }
    return NULL;
}

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

int main()
{
    std::wstring wString;
    wString = L"0x" + uLongToString(15, 16); //Num, Base: 2, 8, 10, 16";
    MessageBoxW(HWND_DESKTOP, (LPCWSTR) &wString, L"RtlIntegerToUnicodeString", MB_OK | MB_TOPMOST);
}
// ****************************************************************************
//
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 18, 2020, 09:48:55 am
Yes, in C/C++ ALL variables must be initialized, except the static ones.

To initialize a WCHAR string you can do this:

WCHAR zString[MAX_PATH] = { 0 };

or

WCHAR zString[MAX_PATH]; ClearMemory(zString, sizeof(zString));

ClearMemory is a procedure from my Tools.h API helper, aka:
void ClearMemory(IN void* mem, IN long nSize) {
    memset(mem, 0, nSize);
}


Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 18, 2020, 09:51:42 am
To convert numeric values to string use these from Tools.h

WCHAR* STRL(IN long N) {
    static WCHAR longstr[33] = {0};
    _ltow_s(N, longstr, 10);
    return (WCHAR*)longstr;
}

WCHAR* STRH(IN long N) {
    static WCHAR hexstr[33] = { 0 };
    swprintf_s(hexstr, strSize(hexstr), L"0x%.8X", N);
    return hexstr;
}

WCHAR* STRF(IN float N) {
    static WCHAR ws[33] = {0};
    swprintf_s(ws, strSize(ws), L"%f", N);
    return (WCHAR*) ws;
}

Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 18, 2020, 10:07:24 am
Note about wstring; while it seems easier to use, the use of class adds extra overhead over direct use of the core API.

I first used wstring because it was closer to what could be done with PB's, however now i am trying to use only WCHAR with my own set of helper functions, to enforce granularity and reduce the size of the framework being used. 

For me small code size has always been my moto, except when i have to work with IL or p-code, because then there is nothing i can do to bypass the bloated dot.NET or WinDev WL.
Title: Re: My contributions on José Roca's forum have gone
Post by: Patrice Terrier on July 18, 2020, 02:12:31 pm
Cousin,

Make sure to read that one:
http://www.objreader.com/index.php?topic=334.0
Title: Re: My contributions on José Roca's forum have gone
Post by: Pierre Bellisle on July 18, 2020, 08:49:51 pm
Salut,

Yep, the string manipulation part is not easy at first, no good BSTR equivalent seems to exist.
One thing I asked myself is what is better, cleaner, and give fewer restrictions.
In C++, there is so many ways to do things... It become confusing.
std::wstring looked interesting, still not easy to use when you want to mix it with pointers.
I'll remember the class overhead you mentioned.
WCHAR seems like a good suggestion, I will try to stick with it.

For now, I won't focus on exe size yet, but more on exploring how to do things.
One important thing though, is to have single exe that do not need external MS DLL that may be unavailable on other computers. I like to write pure portable utilities.

Thank for the C/C++ pitfalls link.
I use a TreeviewEditor to store all this stuff and the "Patrice pitfalls" will fit just fine.

C'est en forgeant qu'on devient forgeron...