• Welcome to Powerbasic Museum 2020-B.
 

C++ 64-bit Address (with LISTBOX dynamic memory allocation)

Started by Patrice Terrier, January 24, 2017, 10:41:13 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

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)

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

James C. Fuller

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

James C. Fuller

Patrice,
  This trims the text in your FindDialogProc ????

    wcscpy(gP.findtext, gP.findtext);

James

Patrice Terrier

#3
QuoteImpressive. 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...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#4
Quotewcscpy(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.


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);
}
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

James--

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

James C. Fuller

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



Patrice Terrier

#7
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.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

James C. Fuller

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


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;
}


Patrice Terrier

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