Author Topic: C++ 64-bit Address (with LISTBOX dynamic memory allocation)  (Read 521 times)

0 Members and 1 Guest are viewing this topic.

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« on: January 24, 2017, 10:41:13 AM »
Here is my 30Kb C++ 64-bit UNICODE version of the PowerBASIC Address demo.

All the hassle of dynamic memory allocation is done by using hidden memory LISTBOX,
using the OS built-in API to perform:
- add
- insert
- delete
- replace
- find
- sort
This could be extended to manipulate any database record structure, working with row and column.

Note: I have not checked everything thoroughly, because my main goal was to show you another {and easy} way to simulate array allocation/manipulation.
The beauty of this concept is that it can be used the same with any programming language  8)

...
« Last Edit: January 24, 2017, 02:55:26 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 662
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #1 on: January 24, 2017, 01:40:14 PM »
Patrice,
  Impressive. I do like the individual listboxes as a data base cols. A little more overhead in deleting a record but not too bad.

James

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 662
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #2 on: January 24, 2017, 02:12:44 PM »
Patrice,
  This trims the text in your FindDialogProc ????

    wcscpy(gP.findtext, gP.findtext);

James

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #3 on: January 24, 2017, 02:17:49 PM »
Quote
Impressive. I do like the individual listboxes as a data base cols.
indeed a good replacement for the use of VECTOR working very well with TCLib.
And fast too...
« Last Edit: January 24, 2017, 02:26:17 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #4 on: January 24, 2017, 02:24:56 PM »
Quote
wcscpy(gP.findtext, gP.findtext);
Forget to remove it, i do not need triming myself.
However if you want it, my own new TRIM {any} functions are into Tools.h.

Code: [Select]
WCHAR* RTRIM$(IN WCHAR* sBuf, IN WCHAR* sChar) {
    long nLength = (long) wcslen(sBuf);
    long nLen = (long) wcslen(sChar);
    if ((nLength) && (nLen)) {
        while (nLength > 0) {
            nLength -= 1;
            if (find_wchar(sChar, &sBuf[nLength]) > -1) {
                sBuf[nLength] = L'\0';
            } else {
                break;
            }
        }
    }
    return sBuf;
}

WCHAR* LTRIM$(IN WCHAR* sBuf, IN WCHAR* sChar) {
    reverse(sBuf, wcslen(sBuf));
    sBuf = RTRIM$(sBuf, sChar);
    reverse(sBuf, wcslen(sBuf));
    return sBuf;
}

WCHAR* TRIM$(IN WCHAR* sBuf, IN WCHAR* sChar) {
    return LTRIM$(RTRIM$(sBuf, sChar), sChar);
}
« Last Edit: January 24, 2017, 02:27:42 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #5 on: January 27, 2017, 10:49:36 AM »
James--

I just checked the print funcion, and it works fine by me  ::)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 662
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #6 on: January 27, 2017, 01:42:01 PM »
Patrice,
  I know you said you are not finished but your print routine is not really in the spirit of the port from PB :)
Your's does not print here, but mine adapted from Fred's post:
http://www.jose.it-berater.org/smfforum/index.php?topic=5182.msg22306#msg22306
prints fine and the output is the same as the PB version.

I tried your exe and then I rebuilt the project and it still fails.
Your "successful print msgbox" pops up immediately
I do get a print tray icon with 0 documents pending that eventually goes away.
It is a network printer if that makes any difference?
Win10 64.

James



Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #7 on: January 27, 2017, 03:21:31 PM »
Mine is also a network printer (EPSON XP-820) shared through my NAS SYNOLOGY via the USB port, and that works well by me.
I can even access it from my ANDROID tablet, my phone-book, and my SAMSUNG SMART TV.  :-[

By the way it could even be used to print/save within an image.
And should produce smaller code size than the one used in PB.

Note: the code you are refering to is written in PowerBASIC not in C++.
and perhaps your printer doesn't support the use of StretchDIBits .
Would be interesting to use zTrace to figure what part of the code fails with your config.

...
« Last Edit: January 27, 2017, 03:46:32 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 662
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #8 on: January 27, 2017, 04:21:02 PM »
Patrice,
  My printer is an HP Officejet Pro 8100.
There are only 2 assignments for nRet. At the dimensioning nRet = 0 and at the nRet = StretchDIBits(.....
I added if (nRet == GDI_ERROR) nRet = 0; right after and it still fails??

This is my interpretation of Fred's PB code.
It makes heavy use of Fred's String class and uses my version of aedynarray.h.

James

Code: [Select]
int PrintRecord (HWND hWnd, AddressTypeArray&  AddArray, int Index)
{
    fstring  fsRec;
    fstring  fsBuffer;
    HFONT    hFont = {0};
    HFONT    hOldFont = {0};
    TEXTMETRIC  tm = {0};
    int      xChar = {0};
    int      yChar = {0};
    int      xPage = {0};
    int      yPage = {0};
    int      i = {0};
    int      iLineCount = {0};
    int      iCharsCopied = {0};
    DWORD    dwBytes = 128;
    DWORD    nBufferSize = 1024;
    DWORD*   dwPtr;
    DWORD    dwWord = {0};
    RECT     rc = {0};
    HDC      hdcPrn = {0};
    DOCINFO  di = {sizeof(DOCINFO), _T("Print1: Printing")};
    HWND     hCtl = {0};
    fsBuffer.Make(0, nBufferSize);
    GetDefaultPrinter(fsBuffer.lpStr(), &dwBytes);
    hdcPrn = CreateDC( NULL, fsBuffer.lpStr(), NULL, NULL);
    if(hdcPrn == NULL )
    {
        return -1;
    }
    hFont = CreateFont(- 1 * ( 15 * GetDeviceCaps( hdcPrn, LOGPIXELSY)) / 72, 0, 0, 0, FW_HEAVY, 0, TRUE, 0, 0, 0, 0, 0, 0, _T("Ariel"));
    fsRec.Make(0, 32);
    GetWindowText(GetDlgItem(hWnd, IDC_INDEX), fsRec.lpStr(), fsRec.Len());
    fstring  fs(_T("Address Book, Record "));
    fs += fsRec;
    xPage = GetDeviceCaps( hdcPrn, HORZRES);
    yPage = GetDeviceCaps( hdcPrn, VERTRES);
    if(StartDoc(hdcPrn, &di) > 0 )
    {
        if(StartPage(hdcPrn) > 0 )
        {
            hOldFont = ( HFONT) SelectObject( hdcPrn, hFont);
            GetTextMetrics(hdcPrn, &tm);
            yChar = tm.tmHeight + tm.tmExternalLeading;
            xChar = tm.tmAveCharWidth;
            rc.top = 200;
            rc.bottom = rc.top + yChar;
            rc.left = 0;
            rc.right = xPage;
            DrawText(hdcPrn, fs.lpStr(), -1, &rc, DT_CENTER);
            DeleteObject(SelectObject(hdcPrn, hOldFont));
            hFont = CreateFont(- 1 * ( 11 * GetDeviceCaps( hdcPrn, LOGPIXELSY)) / 72, 0, 0, 0, FW_HEAVY, 0, 0, 0, 0, 0, 0, 0, 0, _T("Ariel"));
            hOldFont = ( HFONT) SelectObject( hdcPrn, hFont);
            GetTextMetrics(hdcPrn, &tm);
            yChar = tm.tmHeight + tm.tmExternalLeading + 20;
            xChar = tm.tmAveCharWidth;
            TextOut(hdcPrn, 300, 600, _T("Company:"), 8);
            TextOut(hdcPrn, 300, 600 + 1 * yChar, _T("Name:"), 5);
            TextOut(hdcPrn, 300, 600 + 3 * yChar, _T("Address:"), 8);
            TextOut(hdcPrn, 300, 600 + 4 * yChar, _T("City:"), 5);
            TextOut(hdcPrn, 300, 600 + 5 * yChar, _T("State/Prov:"), 11);
            TextOut(hdcPrn, 300, 600 + 6 * yChar, _T("Zip/Postal:"), 11);
            TextOut(hdcPrn, 300, 600 + 7 * yChar, _T("Country:"), 8);
            TextOut(hdcPrn, 300, 600 + 9 * yChar, _T("Phone:"), 6);
            TextOut(hdcPrn, 300, 600 + 10 * yChar, _T("Fax:"), 4);
            TextOut(hdcPrn, 300, 600 + 11 * yChar, _T("Email:"), 6);
            TextOut(hdcPrn, 300, 600 + 12 * yChar, _T("Url:"), 4);
            TextOut(hdcPrn, 300, 600 + 14 * yChar, _T("Comments:"), 9);
            DeleteObject(SelectObject(hdcPrn, hOldFont));
            fsBuffer = AddArray[Index].Company;
            TextOut(hdcPrn, 1000, 600, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].FirstName;
            fsBuffer += _T(" ");
            fsBuffer += AddArray[Index].LastName;
            TextOut(hdcPrn, 1000, 600 + 1 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].Address1;
            TextOut(hdcPrn, 1000, 600 + 3 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].CityName;
            TextOut(hdcPrn, 1000, 600 + 4 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].StateName;
            TextOut(hdcPrn, 1000, 600 + 5 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].ZipCode;
            TextOut(hdcPrn, 1000, 600 + 6 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer.Make(0, 128);
            hCtl = GetDlgItem( hWnd, IDC_COUNTRY);
            GetWindowText(hCtl, fsBuffer.lpStr(), 128);
            TextOut(hdcPrn, 1000, 600 + 7 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].Phone;
            TextOut(hdcPrn, 1000, 600 + 9 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].Fax;
            TextOut(hdcPrn, 1000, 600 + 10 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].Email;
            TextOut(hdcPrn, 1000, 600 + 11 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            fsBuffer = AddArray[Index].Url;
            TextOut(hdcPrn, 1000, 600 + 12 * yChar, fsBuffer.lpStr(), fsBuffer.Len());
            hCtl = GetDlgItem( hWnd, IDC_COMMENTS);
            iLineCount = SendMessage( hCtl, ( UINT) EM_GETLINECOUNT, ( WPARAM) 0, ( LPARAM) 0);
            fsBuffer.Make(0, 1024);
            dwPtr = ( DWORD*) fsBuffer.lpStr();
            for(i = 0; i <= iLineCount - 1; i += 1)
            {
                *dwPtr = MAKELONG( 1024, 0);
                iCharsCopied = SendMessage( hCtl, ( UINT) EM_GETLINE, ( WPARAM) i, ( LPARAM) fsBuffer.lpStr());
                TextOut(hdcPrn, 1000, 600 + (15 + i)*yChar, fsBuffer.lpStr(), iCharsCopied);
            }

            if(EndPage(hdcPrn) > 0 )
            {
                EndDoc(hdcPrn);
            }
        }
    }
    DeleteDC(hdcPrn);
    return 0;
}


Offline Patrice Terrier

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2382
  • Gender: Male
    • www.zapsolution.com
Re: C++ 64-bit Address (with LISTBOX dynamic memory allocation)
« Reply #9 on: January 27, 2017, 04:33:46 PM »
The beauty of WM_PRINT is that is performs a hard copy of the client area, and Windows once again, does most of the work for us, helping to produce smaller code size, and that was my goal  :)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com