• Welcome to Theos PowerBasic Museum 2017.

Recent posts

#11
General Discussion / Re: How to force display/focus...
Last post by John Montenigro - August 29, 2017, 10:57:01 PM
OK, I had a chance to experiment a bit more, and it would appear that GetNextSibling finds that "next window"...

Here's what seems to be working:


Function PerformAltTab As Dword
   Local d As Dword

   d = AfxGetNextSibling(ghDlg)
   SetForegroundWindow(d)
   BringWindowToTop(d)
   SetFocus(d)
   If Err Then Function = %TRUE    ' failed

End Function   



I'll post if I find out anything better.
-John



#12
General Discussion / Re: How to force display/focus...
Last post by John Montenigro - August 29, 2017, 09:18:42 PM
I found some code that I had been experimenting with. I was trying every combination known to man!

Yes, I know this looks crazy, but when you've read everything you can get your hands on and it still makes no sense, you start to experiment...

-John

...in main loop:

   Dialog New 0, "MyApp", s.lDlgLeft, s.lDlgTop, s.lDlgWidth, s.lDlgHeight, %WS_Visible Or %WS_SysMenu Or _
      %WS_MinimizeBox Or %WS_Caption Or %DS_3DLook Or %DS_NoFailCreate Or %DS_SetFont, _
      %WS_Ex_Left Or %WS_Ex_LtrReading Or %WS_Ex_RightScrollbar Or %WS_Ex_ControlParent, To _
      ghDlg




Function PerformAltTab As Dword
   Local d, f As Dword
   Local m As String

   'To check if your application window is the foreground window,
   '  compare the handle returned by GetForegroundWindow
   '  to that of your application window.

   f = GetForegroundWindow
   m &= "GetForegroundWindow:   " & Trim$(f) & $CrLf

   d = AfxGetTopEnabledWindow                                          '1
   m &= "AfxGetTopEnabledWindow: " & Trim$(d)

   'd = AfxGetTopLevelWindow(ghDlg)                         '2    ' NOT the same as the Foreground or TopEnabled
   'd = AfxGetTopLevelWindow(d)                                         '3
   'm &= "AfxGetTopLevelWindow: " & Trim$(d)

   'd = AfxGetTopLevelParent(ghDlg)                         '4
   'd = AfxGetTopLevelParent(d)   ok in combo with last sibling?        '5

   'd = AfxGetFirstChild(ghDlg)                             '6
   'd = AfxGetFirstChild(d)                                             '7

   'd = AfxGetFormHandle(ghDlg)                             '8
   'd = AfxGetFormHandle(d)                                             '9

   'd = AfxGetFirstSibling(ghDlg)                           '10
   d = AfxGetFirstSibling(d)                                           '11

   'd = AfxGetLastSibling(ghDlg)                            '12
   'd = AfxGetLastSibling(d)                                            '13

   'd = AfxGetNextSibling(ghDlg)    ' shows promise!        '14
   d = AfxGetNextSibling(d)    ' shows promise!                        '15
   'd = AfxGetNextSibling(d)    ' shows promise!                        '16
   'd = AfxGetNextSibling(d)    ' shows promise!                        '17

   'd = AfxGetPrevSibling(ghDlg)      ' not good!           '18
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '19
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '20
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '21

   ? m,,"experimenting"

'   AfxForceSetForegroundWindow(d)
'these stay together:                                                   ' 4 + 7 + 15 = self
   SetForegroundWindow(d)
   BringWindowToTop(d)
   SetFocus(d)
End Function
#13
General Discussion / How to force display/focus to ...
Last post by John Montenigro - August 29, 2017, 08:48:49 PM
In PB Win10.04, I'm writing a small app to automate loading of data into a program that has no import ability, so I'm using SendKeys.inc to load its key buffer.
However, I would like to assure the user that the data won't just pour into any open window, so I'm trying to activate the "last window" that was active. It is possible that my app may sit idle for awhile, and the user may do many other tasks in other windows before starting the transfer, so I cannot rely on which window was "last active" at the time my app started running; it has to be at the time the transfer button is clicked.

Here's my confusion: I have read tons of material about SetFocus and all those related parent/child, visible/hidden API functions, but I have not found the right way to identify which window would be brought forward as if the user pressed ALT-TAB. It seems the more I read, the less I understand. I've even bought 2 antique books on Win32 programming, but this is still eluding me.

I *THINK* I'm supposed to find the window that is "next" in the z-order from the top (the one "below" my app), and ignore its Child windows and find their parent. Is this the right way?

I'm at work now, so cannot post code, but I'll return tomorrow with samples of what I've tried (that didn't work).

Meanwhile, if anyone can point me in the direction of good, clear information, I'd be grateful and read it right away.

Thanks!
-John



#14
C++ WinLIFT / GDImage / Re: New {multi} media player
Last post by Patrice Terrier - August 17, 2017, 06:56:35 PM
.SRT support has been added to display subtitles while playing a movie.

I wrote my own .srt decoder that is very effective, because addon like XySubfilter works only with DrectShow and is very bloated (1747 Kb).
#15
Addon tools for PB / Re: zTrace 1.52 (debugging uti...
Last post by Patrice Terrier - August 11, 2017, 08:10:36 PM
#16
Addon tools for PB / Re: zTrace32.dll v3
Last post by Marc Pons - August 11, 2017, 04:17:11 PM
Hello Patrice

I wanted to use your nice ztrace tool v3 with unicode on window 32

but i've found only the win 64

so i've adapted a litle your code to be able to compile with mingw  gcc or g++


//+--------------------------------------------------------------------------+
//|                                                                          |
//|                               zTrace 3.00                                |
//|                                                                          |
//|                      Win32 SDK debugging window DLL                      |
//|                                                                          |
//+--------------------------------------------------------------------------+
//|                                                                          |
//|                         Author Patrice TERRIER                           |
//|                                                                          |
//|                         copyright(c) 2009-2017                           |
//|                                                                          |
//|                Patrice Terrier http://www.zapsolution.com                |
//|                                                                          |
//+--------------------------------------------------------------------------+
//|                  Project started on : 04--2009 (MM-DD-YYYY)            |
//|                        Last revised : 04-27-2017 (MM-DD-YYYY)            |
//+--------------------------------------------------------------------------+

// link to gdi32  and comdlg32  libs with g++ compiler at least for win 32
// for win 64 probably same ?

#ifndef UNICODE
# define UNICODE
#endif

#include <windows.h>

#if defined(__MINGW32__) || defined(__MINGW64__)
# if defined(__MINGW64__)
#  define A_CAPTION   "zTrace 3.00 64-bit"
#  define WND_CAPTION   L"zTrace 3.00 64-bit"
# else
#  define A_CAPTION   "zTrace 3.00 32-bit"
#  define WND_CAPTION   L"zTrace 3.00 32-bit"
# endif
#endif

#define WND_Style   (WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME)
#define WND_ExStyle (WS_EX_TOOLWINDOW)

#define HORIZONTAL_EXTENT    6000  // Maximum value for the horizontal scrollbar
#define MIN_WIDTH            300   // default client width size
#define MIN_HEIGHT           65    // default client height size

#define ID_LISTBOX           1

#define IDM_About            101  // menu popup
#define IDM_Hscroll          103  // menu popup
#define IDM_Print            104  // menu popup
#define IDM_CopyToClipboard  105  // menu popup
#define IDM_ClearContent     106  // menu popup
#define IDM_TopMost          107  // menu popup
#define IDM_Unicode          108  // menu popup
#define IDM_Debug            109  // menu popup
#define IDM_SaveCoordinates  110  // menu popup

typedef struct SETBIN
{
    long   x;
    long   y;
    long   w;
    long   h;
    long   topmost;
    long   savecoordinates;
    long   usescrollbar;
    long   debug;
    long   unicode;
}t_SETBIN;

typedef struct PROP
{
    t_SETBIN bin;
    HBRUSH backbrush;
    HWND   hWnd;
    HWND   hCtrl;
}t_PROP;

t_PROP gP;

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

/* Returns TRUE on success, FALSE on failure */
return TRUE;
}


void zLoadSaveCoordinates (IN long RW)
{
    HANDLE hFile;
    DWORD dwBytes = 0;

    WCHAR zPath[MAX_PATH];
    __stosb((LPBYTE)&zPath, 0, MAX_PATH * 2);
    GetTempPath(MAX_PATH - 12, zPath);
    lstrcat(zPath, L"zTrace3.cfg");

    if (RW)
    {
        hFile = CreateFile(zPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile != INVALID_HANDLE_VALUE)
        {
            WriteFile(hFile, &gP.bin, sizeof(gP.bin), &dwBytes, NULL);
            CloseHandle(hFile);
        }
    }
    else
    {
        __stosb((LPBYTE)&gP.bin, 0, sizeof(gP.bin));
        hFile = CreateFile(zPath, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile != INVALID_HANDLE_VALUE)
        {
            DWORD FileSizeHigh = 0;
            if (GetFileSize(hFile, &FileSizeHigh) == sizeof(gP.bin) && FileSizeHigh == 0)
            {
                ReadFile(hFile, &gP.bin, sizeof(gP.bin), &dwBytes, NULL);
                CloseHandle(hFile);
            }
        }

        if ((gP.bin.w == 0) || (gP.bin.h == 0))
        {
            gP.bin.w = MIN_WIDTH;
            gP.bin.h = MIN_HEIGHT;
            gP.bin.x = 0;
            gP.bin.y = 0;
        }
    }
}

void zDebug (WCHAR* zMessage)
{
    static HANDLE hDebug = NULL;
    if (!zMessage)
    {
        if (hDebug)
        {
            CloseHandle(hDebug);
            hDebug = NULL;
        }
        return;
    }
    long Creation = 0;
    if (*zMessage)
    {
        DWORD BytesWritten = 0;
        if (!hDebug)
        {
            hDebug = CreateFile(L"zDebug.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hDebug)
                Creation = -1;
        }
        if (hDebug)
        {
            if (gP.bin.unicode)   // UNICODE
            {
                WriteFile(hDebug, zMessage, lstrlen(zMessage), &BytesWritten, NULL);
                WriteFile(hDebug, L"\r\n", 4, &BytesWritten, NULL);
            }
            else                  // ANSI
            {
                if (Creation)
                    WriteFile(hDebug, "\xEF\xBB\xBF", 3, &BytesWritten, NULL);    // UTF-8 BOM
                long length = WideCharToMultiByte(CP_UTF8, 0, zMessage, -1, NULL, 0, NULL, NULL);
                if (length > 1)   // excluding NUL terminator
                {
                    LPSTR buffer = (LPSTR)GlobalAlloc(GPTR, length);
                    if (buffer)
                    {
                        WideCharToMultiByte(CP_UTF8, 0, zMessage, -1, buffer, length, NULL, NULL);
                        WriteFile(hDebug, buffer, length - 1, &BytesWritten, NULL);
                        WriteFile(hDebug, "\r\n", 2, &BytesWritten, NULL);
                        GlobalFree(buffer);
                    }
                }
            }
        }
    }
}

void SendUnicodeToClipboard(HWND hWnd)
{
    long nCount = (long)SendMessage(gP.hCtrl, LB_GETCOUNT, 0L, 0L);
    if (nCount > 0)
    {
        long K, index, cch, bufsize = 0;
        long *pSelItems = NULL;
        long nSelItems = (long)SendMessage(gP.hCtrl, LB_GETSELCOUNT, 0L, 0L);
        if (nSelItems > 0)
        {
            nCount = 0;
            pSelItems = (long *)GlobalAlloc(GPTR, nSelItems * sizeof(long));
            if (pSelItems)
            {
                nCount = nSelItems;
                SendMessage(gP.hCtrl, LB_GETSELITEMS, nSelItems, (LPARAM)pSelItems);
            }
        }
        for (K = 0; K < nCount; K++)
        {
            index = pSelItems ? pSelItems[K] : K;
            cch = (long)SendMessage(gP.hCtrl, LB_GETTEXTLEN, (WPARAM)index, 0L);
            if (cch > 0)
                bufsize += cch + 2;
        }
        if (bufsize > 0)
        {
            HGLOBAL hClipData = GlobalAlloc(GHND | GMEM_DDESHARE, (bufsize + 1) * sizeof(WCHAR));
            LPTSTR  buffer = (LPTSTR)GlobalLock(hClipData);
            int offset = 0;
            for (K = 0; K < nCount; K++)
            {
                index = pSelItems ? pSelItems[K] : K;
                cch = (long)SendMessage(gP.hCtrl, LB_GETTEXTLEN, (WPARAM)index, 0L);
                if (cch > 0)
                {
                    if ((offset + cch + 2) > bufsize)
                        break;
                    cch = (long)SendMessage(gP.hCtrl, LB_GETTEXT, (WPARAM)index, (LPARAM)(buffer + offset));
                    offset += cch;
                    buffer[offset++] = '\r';
                    buffer[offset++] = '\n';
                }
            }
            buffer[bufsize] = 0;
            GlobalUnlock(hClipData);
            if (OpenClipboard(0))
            {
                EmptyClipboard();
                SetClipboardData(CF_UNICODETEXT, hClipData);
                CloseClipboard();
            }
            else
                GlobalFree(hClipData);
        }
    }
}

void DebugRefresh(IN HWND hWnd)
{
    if (gP.bin.debug)
    {
        long nCount = (long)SendMessage(gP.hCtrl, LB_GETCOUNT, 0, 0);
        if (nCount > 0)
        {
            for (long i = 0; i < nCount; i++)
            {
                long cch = (long)SendMessage(gP.hCtrl, LB_GETTEXTLEN, (WPARAM)i, 0L);
                if (cch > 0)
                {
                    LPTSTR pStr = (LPTSTR)GlobalAlloc(GPTR, (cch + 1) * sizeof(WCHAR));
                    if (pStr)
                    {
                        cch = (long)SendMessage(gP.hCtrl, LB_GETTEXT, (WPARAM)i, (LPARAM)pStr);
                        zDebug((LPWSTR)pStr);
                        GlobalFree(pStr);
                    }
                }
            }
        }
    }
    else
        zDebug(NULL); // Close zDebug.txt if already open.
}

LRESULT CALLBACK ToolProc(IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
{
    RECT rc, rw;
    long nCount;
    HMENU hMenu;

    switch (uMsg)
    {
    case WM_CREATE:
        gP.backbrush = CreateSolidBrush(0x00FFFF);
        break;

    case WM_GETMINMAXINFO:
        SetRect(&rc, 0, 0, MIN_WIDTH, MIN_HEIGHT);
        AdjustWindowRectEx(&rc, WND_Style, FALSE, WND_ExStyle);  // Adjust Window To True Requested Size
        ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = rc.right;
        ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = rc.bottom;
        break;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDCANCEL:
            if (HIWORD(wParam) == BN_CLICKED)
            {
                SendMessage(hWnd, WM_CLOSE, 0, 0);
                return 0;
            }
            break;

        case IDM_About:
        // change here to MessageBoxA because pb with // why?
            MessageBoxA(0,
                        "               Debugging window\n"
                        "\n"
                        "  Copyright © 2017 Patrice TERRIER\n"
                        "          pterrier@zapsolution.com\n"
                        "\n"
                        "        http://www.zapsolution.com \n",
                        A_CAPTION , MB_OK);
            break;

        case IDM_Hscroll:
            gP.bin.usescrollbar = !gP.bin.usescrollbar;
            if (gP.bin.usescrollbar)
            {
                ShowScrollBar(gP.hCtrl, SB_HORZ, TRUE);
                SendMessage(gP.hCtrl, LB_SETHORIZONTALEXTENT, HORIZONTAL_EXTENT, 0);
            }
            else
            {
                SendMessage(gP.hCtrl, LB_SETHORIZONTALEXTENT, 1, 0);
                ShowScrollBar(gP.hCtrl, SB_HORZ, FALSE);
            }
            UpdateWindow(gP.hCtrl);
            break;

        case IDM_Print:
            nCount = (long)SendMessage(gP.hCtrl, LB_GETCOUNT, 0L, 0L);
            if (nCount > 0)
            {
                PRINTDLG pd;
                __stosb((LPBYTE)&pd, 0, sizeof(pd));
                pd.lStructSize = sizeof(pd);
                // get rid of PD_RETURNDEFAULT on the line below if you'd like to
                // see the "Printer Settings" dialog!
                pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
                if (PrintDlg(&pd))
                {
                    HDC hPrinter = pd.hDC;

                    HFONT hOldfont, hFont;
                    hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT);

                    if (hOldfont = (HFONT)SelectObject(pd.hDC, hFont))
                    {
                        TEXTMETRIC tm;
                        __stosb((LPBYTE)&tm, 0, sizeof(tm));
                        GetTextMetrics(pd.hDC, &tm);

                        long yChar = tm.tmHeight + tm.tmExternalLeading;
                        //long nLinesPerPage = GetDeviceCaps(pd.hDC, VERTRES) / yChar;
                        //long nCharsPerLine = GetDeviceCaps(pd.hDC, HORZRES) / tm.tmAveCharWidth;

                        DOCINFO di;
                        __stosb((LPBYTE)&di, 0, sizeof(di));
                        di.cbSize = sizeof(di);
                        StartDoc(hPrinter, &di);
                        StartPage(hPrinter);
                        {
                            long* pSelItems = NULL;
                            long nSelItems = (long)SendMessage(gP.hCtrl, LB_GETSELCOUNT, 0L, 0L);
                            if (nSelItems > 0)
                            {
                                nCount = 0;
                                pSelItems = (long*)GlobalAlloc(GPTR, nSelItems * sizeof(long));
                                if (pSelItems)
                                {
                                    nCount = nSelItems;
                                    SendMessage(gP.hCtrl, LB_GETSELITEMS, nSelItems, (LPARAM)pSelItems);
                                }
                            }
                            for (long i = 0; i < nCount; i++)
                            {
                                long index = pSelItems ? pSelItems[i] : i;
                                long cch = (long)SendMessage(gP.hCtrl, LB_GETTEXTLEN, (WPARAM)index, 0L);
                                if (cch > 0)
                                {
                                    LPTSTR pStr = (LPTSTR)GlobalAlloc(GPTR, (cch + 1) * sizeof(WCHAR));
                                    if (pStr)
                                    {
                                        cch = (long)SendMessage(gP.hCtrl, LB_GETTEXT, (WPARAM)index, (LPARAM)pStr);
                                        TextOut(pd.hDC, 0, (yChar * i), pStr, cch);
                                        GlobalFree(pStr);
                                    }
                                }
                            }
                            if (pSelItems)
GlobalFree(pSelItems);
                        }
                        EndPage(hPrinter);
                        EndDoc(hPrinter);
                        SelectObject(pd.hDC, hOldfont); // Good pratice
                        DeleteDC(hPrinter);
                    }
                }
            }
            break;

        case IDM_CopyToClipboard:
            SendUnicodeToClipboard(hWnd);
            break;

        case IDM_ClearContent:
            SendMessage(gP.hCtrl, LB_RESETCONTENT, 0, 0);
            break;

        case IDM_TopMost:
            gP.bin.topmost = !gP.bin.topmost;
            //if (gP.bin.topmost) {
            //    SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
            //} else {
            //    SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
            //}
            SetWindowPos(hWnd, gP.bin.topmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
            break;

        case IDM_Unicode:
            gP.bin.unicode = !gP.bin.unicode;
            DebugRefresh(hWnd);
            break;

        case IDM_Debug:
            gP.bin.debug = !gP.bin.debug;
            DebugRefresh(hWnd);
            break;

        case IDM_SaveCoordinates:
            gP.bin.savecoordinates = !gP.bin.savecoordinates;
            break;
        }
        break;

    case WM_CTLCOLORDLG:
        SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
        return (LRESULT)GetStockObject(NULL_BRUSH);

    case WM_CTLCOLORLISTBOX:
        // wParam is handle of control's display context (hDC)
        // lParam is handle of control
        //------------------------------------------------------
        if ((HWND)lParam == gP.hCtrl)
        {
            SetBkColor((HDC) wParam, 0x00FFFF);
            return (LRESULT) gP.backbrush;
        }
        break;

    case WM_RBUTTONDOWN:
        hMenu = CreatePopupMenu();
        if (hMenu)
        {
            long menuStyle;
            AppendMenu(hMenu, MF_STRING, IDM_About            , L"About");
            AppendMenu(hMenu, MF_SEPARATOR, 102               , L"");
            if (gP.bin.usescrollbar)
                menuStyle = MF_STRING | MF_CHECKED;
            else
                menuStyle = MF_STRING;
            AppendMenu(hMenu, menuStyle,  IDM_Hscroll         , L"Use horizontal scrollbar");
            AppendMenu(hMenu, MF_STRING,  IDM_Print           , L"Send selection to printer");
            AppendMenu(hMenu, MF_STRING,  IDM_CopyToClipboard , L"Copy selection to clipboard");
            AppendMenu(hMenu, MF_STRING,  IDM_ClearContent    , L"Clear content");
            if (gP.bin.topmost)
                menuStyle = MF_STRING | MF_CHECKED;
            else
                menuStyle = MF_STRING;
            AppendMenu(hMenu, menuStyle,  IDM_TopMost         , L"Set window TopMost");
            if (gP.bin.unicode)
                menuStyle = MF_STRING | MF_CHECKED;
            else
                menuStyle = MF_STRING;
            AppendMenu(hMenu, MF_SEPARATOR, 102               , L"");
            AppendMenu(hMenu, menuStyle,  IDM_Unicode         , L"Use Unicode in zDebug.txt");
            if (gP.bin.debug)
                menuStyle = MF_STRING | MF_CHECKED;
            else
                menuStyle = MF_STRING;
            AppendMenu(hMenu, menuStyle,  IDM_Debug           , L"Create zDebug.txt report");
            if (gP.bin.savecoordinates)
                menuStyle = MF_STRING | MF_CHECKED;
            else
                menuStyle = MF_STRING;
            AppendMenu(hMenu, MF_SEPARATOR, 102               , L"");
            AppendMenu(hMenu, menuStyle,  IDM_SaveCoordinates , L"Save window coordinates");

            POINT p;
            GetCursorPos(&p);
            long nChoice = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, p.x, p.y, hWnd, NULL);
            DestroyMenu(hMenu);
            if (nChoice)
                SendMessage(hWnd, WM_COMMAND, MAKELONG(nChoice, 0), 0);
        }
        break;

    case WM_SIZE:
        if (wParam == SIZE_MINIMIZED)
            break;
        gP.bin.w = LOWORD(lParam);
        gP.bin.h = HIWORD(lParam);
        MoveWindow(gP.hCtrl, 0, 0, gP.bin.w, gP.bin.h, TRUE);
        UpdateWindow(hWnd);
    case WM_MOVE:
        GetWindowRect(hWnd, &rw);
        gP.bin.x = rw.left;
        gP.bin.y = rw.top;
        break;

    case WM_DESTROY:
        if (gP.backbrush)
        {
            DeleteObject(gP.backbrush);
            gP.backbrush = 0;
            zLoadSaveCoordinates(1);
        }
        zDebug(NULL);
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

long AddString(IN HWND hCtrl, WCHAR* zPtr)
{
    long nRet = LB_ERR;
    if (zPtr)
    {
        if (gP.bin.debug)
            zDebug(zPtr);
        nRet = (long) SendMessage(hCtrl, LB_ADDSTRING, 0, (LPARAM) zPtr);
        SendMessage(hCtrl, LB_SETTOPINDEX, (WPARAM) nRet, 0);
    }
    return nRet;
}

DWORD WINAPI ShowPopup(IN WCHAR* zPtr)
{
    DWORD nRet = 0;
    HINSTANCE hInstance = GetModuleHandle(NULL);

    WNDCLASSEX wcx;
    __stosb((LPBYTE)&wcx, 0, sizeof(wcx));
    wcx.cbSize = sizeof(wcx);
    long IsInitialized = GetClassInfoEx(hInstance, WND_CAPTION, &wcx);
    if (IsInitialized    == 0)
    {
        wcx.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
        wcx.lpfnWndProc   = &ToolProc;
        wcx.cbClsExtra    = 0;
        wcx.cbWndExtra    = 0;
        wcx.hInstance     = hInstance;
        wcx.hIcon         = 0;
        wcx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcx.hbrBackground = (HBRUSH) COLOR_BTNSHADOW;
        wcx.lpszMenuName  = NULL;
        wcx.lpszClassName = WND_CAPTION;
        wcx.hIconSm       = wcx.hIcon;
        if (RegisterClassEx(&wcx))
            IsInitialized = TRUE;
    }
    if (IsInitialized)
    {
        zLoadSaveCoordinates(0);
        RECT rc;
        SetRect(&rc, 0, 0, gP.bin.w, gP.bin.h);
        AdjustWindowRectEx(&rc, WND_Style, FALSE, WND_ExStyle);  // Adjust Window To True Requested Size
        gP.hWnd = CreateWindowEx(WND_ExStyle, WND_CAPTION, WND_CAPTION, WND_Style, gP.bin.x, gP.bin.y, rc.right - rc.left, rc.bottom - rc.top, 0, 0, hInstance, NULL);
        if (gP.hWnd)
        {
            DWORD nStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_MULTIPLESEL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | LBS_DISABLENOSCROLL;
            gP.hCtrl = CreateWindowEx(0, L"ListBox", NULL, nStyle, 0, 0, gP.bin.w, gP.bin.h, gP.hWnd, (HMENU) ID_LISTBOX, hInstance, NULL);

            HFONT hFont = CreateFont(-13, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, FF_MODERN | FIXED_PITCH, L"Courier New");
            if (hFont) SendMessage(gP.hCtrl, WM_SETFONT, (WPARAM)hFont, 0L);

            AddString(gP.hCtrl, zPtr);

            if (gP.bin.usescrollbar)
            {
                SendMessage(gP.hCtrl, LB_SETHORIZONTALEXTENT, HORIZONTAL_EXTENT, 0);
                ShowScrollBar(gP.hCtrl, SB_HORZ, TRUE);
            }
            else
                ShowScrollBar(gP.hCtrl, SB_HORZ, FALSE);


            if (gP.bin.topmost)
                SetWindowPos(gP.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
            else
                ShowWindow(gP.hWnd, SW_SHOW);

            UpdateWindow(gP.hWnd);

            MSG msg;
            while (GetMessage(&msg, NULL, 0, 0))
            {
                // Easier to detect the right mouse button click on the listBox from the message pump
                if ((msg.hwnd == gP.hCtrl) && (msg.message == WM_RBUTTONDOWN))
                    ToolProc(gP.hWnd, WM_RBUTTONDOWN, 0, 0);
                else
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }

            DeleteObject(hFont);
            nRet = (DWORD)msg.wParam;
        }
    }
    return nRet;
}

#ifdef __cplusplus
  extern "C" {
#endif
    __declspec(dllexport)long   zTrace(WCHAR* zPtr)
    {
        long nRet = LB_ERR;
        if (gP.hWnd == NULL)
        {
            DWORD dwThreadId = 0;
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ShowPopup, zPtr, 0, &dwThreadId);
            if (hThread)
            {
                Sleep(100);
                CloseHandle(hThread);
                nRet = 0;
            }
        }
        else
            nRet = AddString(gP.hCtrl, zPtr);
        return nRet;
    }
#ifdef __cplusplus
  }
#endif




it worked perfectly

the bat file to compile and create the interface for dll  libzTrace32.dll.a  (for mingw  toolchain compilers )

@echo off

Rem check here  where is your main compiler folder
SET var=E:\mingw-w64-5.3.0\mingw32\

Rem check here also where are your libgdi32.a  & libcomdlg32.a
SET var2=%var%i686-w64-mingw32\

SET lib32=%var2%lib\



@REM TODO: Set PATH's for this session.
SET PATH=%var%bin;%var%i686-w64-mingw32\bin;

SET MINGW_INCLUDE=%var%include
SET MINGW_LIB=%var%lib
echo.
echo  Path for compilation  : %var%
echo.
echo.

@echo Compile
gcc  -c zTrace32.c -o zTrace32.o
@echo.
@echo link
gcc -shared -o zTrace32.dll zTrace32.o %lib32%libgdi32.a %lib32%libcomdlg32.a  -s -Wl,--out-implib,libzTrace32.dll.a
@echo.
pause


it produce 25ko dll

i suppose it works also on 64bit compiler

Encore merci pour ce super outil très pratique, et pour avoir publié le code également.

Je le diffuse largement autour de moi...  en indiquant l'auteur naturellement.

bye


attached the codes and 32 dll




#17
OpenGL (Open Graphics Library) / Re: OpenGL: Spinning Triangle
Last post by Patrice Terrier - August 11, 2017, 10:08:56 AM
SDK style code is the same in C++ and PB, and the OpenGL syntax is strictly the same for all languages i know.

Here is another link showing the use of spinner in PB.
http://www.jose.it-berater.org/smfforum/index.php?topic=4084.0
#18
OpenGL (Open Graphics Library) / Re: OpenGL: Spinning Triangle
Last post by Chris Chancellor - August 10, 2017, 04:42:50 PM
Thanxx Patrice,  it is beautiful but is in c++  :o
#19
OpenGL (Open Graphics Library) / Re: OpenGL: Spinning Triangle
Last post by Patrice Terrier - August 10, 2017, 10:46:37 AM
Go there http://nehe.gamedev.net/ if you want to learn the basic of OpenGL.
Another alternative to do what you want is to create a spinner animation.
See also this project
http://www.objreader.com/index.php?topic=92.0
#20
OpenGL (Open Graphics Library) / Re: OpenGL: Spinning Triangle
Last post by Chris Chancellor - August 09, 2017, 05:42:23 PM
Hello

I would like to know how to place in a background text  like "Please wait ..."  behind this spinning triangle ?
it would be real nice to have this text display 
thanxx