• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

HUD window 64-bit demo

Started by Patrice Terrier, October 03, 2013, 08:53:26 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

This 64-bit project shows you the future...

It is based on a mix of WinLIFT 5.00 and GDImage 7.00.



What are the points:

  • Multi-thread.
  • 64-bit code calling 32-bit applications (OpenGL visual plugins).
  • Mix of animated sprites and static image altogether.
  • All the animations are working in concurent mode, even when you drag the window or when you move an object.
  • Low CPU foot print.
  • Multiple DWM composited layers.
  • Zoom and full 360° image rotation.
  • Small code size (No MFC, no ATL, no additional framework).
  • Audio drag and drop from the explorer (to play MP3 and OGG).
  • Full HUD skin theme.
  • All the graphics objects can be movable, locked, and/or anchored to any specific location.
  • WinLIFT spinner gauge controls (use right mouse click to restore the original angle).
  • HUD frames could be changed on the fly by clicking on the top-left Neytiri icon.

To start playing audio, use the checkbox "Play visual plugin".
(And remember that you can also drag and drop audio files from the Explorer.)

The 28095 Mb release ZIP project is here.

Note 1: To avoid any UAC problem unlock the ZIP file before unpacking the files into a dedicated folder.

Note 2: Better to use HUDplus.exe hover a dark Windows desktop wallpaper.

Note 3: The VS2010 project would be packed into a distinct ZIP files, but without the release DLL(s) nor the resources, for smaller zip file (and would be attached to this post).
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#1
This test has been done on Windows 7, 64-bit.

I am using the same C++ VS2010 source code to create the 32 and 64-bit release version, and both EXE are playing the same audio file and same sprite animations.

The 64-bit version is using almost 25% to 50% less CPU than the 32-bit, while the memory used by the 64-bit is only 7% larger than the 32-bit.

Disk size of HUDPLUS.exe 32-bit: 90 Kb
Disk size of HUDPLUS.exe 64-bit: 106 Kb (17% larger)

It is clear than generating native code matching the host processor gives better result.

Food for thought, for those who have been abused for years.  >:(

See below the attached screen shot:
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#2

  • I have reworked the whole project to use specific spinner animations for each of the plugins.
  • I have added a new audio track.
  • Changed the window size from 4/3 to 16/9 (to look more modern).
  • Added a new black HUD theme.
  • When you play audio it is important to check the "Transparent HUD mode".

The link to download this new demo has been updated into the first post of this thread, as well as the screen shot.

GDImage 7.00 is able to manipulate the spinners just like regular sprite but with zooming and full 360° rotation, without noticeable impact on the animation speed.
It could even be possible to adjust the animation speed to the tempo of the music.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#3
Here is the source code to the HUDplus project, that could be compiled either to 32 or 64-bit.

Using the core SDK syntax helps me to port the code from one language to another (PowerBASIC, WinDev, C/C++),
and keeps the code more readable (at least for me).


#include "stdafx.h"
#include <windows.h>
#include <Commctrl.h>
#include <vector>

//#include "zTrace.h"   // Search in the same directory of the current file.
#pragma comment(lib, "D:\\VS2010\\GDImage64.lib")
#pragma comment(lib, "D:\\VS2010\\GDImage32.lib")
#include "GDImage.h"
#pragma comment(lib, "D:\\VS2010\\WinLIFT64.lib")
#pragma comment(lib, "D:\\VS2010\\WinLIFT32.lib")
#include "WinLIFT.h"  // Search in the same directory of the current file.

#define _SCL_SECURE_NO_WARNINGS // No warning message when using sprintf, strcopy, etc.

#define NM_AUDIOCOMPLETION  NM_FIRST - 80

#define MyWindowWidth       800 // This value is for the initial 4/3 window size, but it is resized to 16/9 just before being displayed.
#define MyWindowHeight      614 // This value is for the initial 4/3 window size, but it is resized to 16/9 just before being displayed.

#define IDC_STATIC          -101
#define IDC_MAIN_GDIMAGE    1001
#define IDC_MAIN_SLIDEZOOM  1002
#define IDC_MAIN_CHECKBOX   1003
#define IDC_MAIN_CLOCK      1004
#define IDC_MAIN_KNOBLEFT   1005
#define IDC_MAIN_KNOBBIG    1006
#define IDC_MAIN_KNOBRIGHT  1007
#define IDC_MAIN_LOADIMAGE  1008
#define IDC_MAIN_STATICIMG  1009
#define IDC_MAIN_PLUGIN     1010
#define IDC_MAIN_WALLPAPER  1011

#define IDC_CB_PLUGIN       1012
#define IDC_CB_AUDIO        1013

// GDImage constant to identify each sprite image.
#define ID_PHOTO            1
#define ID_LOGO             2
#define ID_SPIN01           3
#define ID_SPIN02           4
#define ID_SPIN03           5

#define TIMER_DELAY         33 // Initial animation value.

// Global variables
HINSTANCE g_hInst;    // Current instance
HWND g_hImageCtrl, g_hMain;
wstring g_sAudioPath, g_sPluginPath, g_sResourcePath;
long g_nFocusID, g_nTrueWidth, g_nTrueHeight, g_nUseWidth, g_nUseHeight, g_nDelay;
float g_rWasZoom;
long WM_ZWPNOTIFICATION;

// Declaration of the functions being used in this module:
HWND    ZWP_Handle();

#define stringW(str) ((WCHAR*) wstring(str.begin(), str.end()).c_str())
#define long_proc typedef long (__stdcall *zProc)

long zTrace (IN wstring sPtr) {
    long nRet = 0;
    static HMODULE hDll;
    if (hDll == 0) {
        if (sizeof(LONG_PTR) == 8) {
            hDll = LoadLibrary(L"zTrace64"); }
        else {
            hDll = LoadLibrary(L"zTrace32");
        }
    }
    if (hDll) {
        long_proc (WCHAR*);
        zProc hProc = (zProc) GetProcAddress(hDll, "zTrace");
        if (hProc) { nRet = hProc((WCHAR*) sPtr.c_str()); }
    }
    return nRet;
}

void Animate (IN LPVOID Delay) {
    DWORD nWait = 0;
    long nFrame;
    for (;;) {
        nFrame = ZD_GetObjectFrameToUse(ID_SPIN01) + 1; if (nFrame > ZD_GetObjectFrameCount(ID_SPIN01)) { nFrame = 1; }
        ZD_SetObjectFrameToUse(ID_SPIN01, nFrame, FALSE);

        nFrame = ZD_GetObjectFrameToUse(ID_SPIN02) + 1; if (nFrame > ZD_GetObjectFrameCount(ID_SPIN02)) { nFrame = 1; }
        ZD_SetObjectFrameToUse(ID_SPIN02, nFrame, FALSE);

        nFrame = ZD_GetObjectFrameToUse(ID_SPIN03) + 1; if (nFrame > ZD_GetObjectFrameCount(ID_SPIN03)) { nFrame = 1; }
        ZD_SetObjectFrameToUse(ID_SPIN03, nFrame, TRUE);

        Sleep((long) g_nDelay);
    }
}

long StartAnimation (IN long Delay) {
    long nRet = LB_ERR;
    g_nDelay = Delay;
    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL,                                  // default security attributes
                                  0,                                     // use default stack size 
                                  (LPTHREAD_START_ROUTINE ) Animate,     // thread function name
                                  (LPVOID) Delay,                        // argument to thread function
                                  0,                                     // use default creation flags
                                  &dwThreadId);                          // returns the thread identifier
    if (hThread) { nRet = 0; Sleep(100); }
    CloseHandle(hThread);
    return nRet;
}

wstring EXEpath() {
    wstring sResult;
    WCHAR exepath[MAX_PATH] = {0};
    if (GetModuleFileName(0, exepath, sizeof(exepath))) {
       sResult = exepath;
       sResult = sResult.substr( 0, sResult.rfind(L"\\"));
       sResult += L"\\";
    }
    return sResult;
}

string ws2s(IN wstring ws) {
    long nLen;
    long nwsLength = (long)ws.length() + 1;
    nLen = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), nwsLength, 0, 0, 0, 0);
    string s(nLen, '\0');
    WideCharToMultiByte(CP_ACP, 0, ws.c_str(), nwsLength, &s[0], nLen, 0, 0);
    return s;
}

void ComboSelectPlus ( HWND hCombo, long nSelected) {
    if (nSelected > 0) { nSelected -= 1; } // Because ListBox is zero based.
    if (hCombo) { SendMessage(hCombo, CB_SETCURSEL, nSelected, 0); }
}

void DetectAudio (HWND hCombo, long nUseItem) {

    if (!hCombo) return;

    long nCount = 0, nPos = 0;
    HANDLE hFind = 0;
    WIN32_FIND_DATAW fd;
    WCHAR zTmp[MAX_PATH] = {0};
    WCHAR zExt[8] = {0};
    wstring sExt;

    SendMessage(hCombo, CB_RESETCONTENT, 0, 0);

    wstring sAudio = L".xm.mod.it.s3m.mo3.mp3.ogg.";
    wstring sSearch = g_sAudioPath; sSearch += L"*.*";
    wcscpy_s(zTmp, (WCHAR*) sSearch.c_str());
    hFind = FindFirstFile(zTmp, &fd);
    nCount = 0;
    nPos = 0;
    if (hFind != INVALID_HANDLE_VALUE) {
       int IsOk = -1;
       while (IsOk != 0) {
          if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
             sSearch = fd.cFileName;
             wcscpy_s(zTmp, (WCHAR*) sSearch.c_str());
             nPos = (long) sSearch.find_last_of(L"."); // Extract extension.
             sExt = sSearch.substr(nPos); sExt += L".";
             wcscpy_s(zExt, (WCHAR*) sExt.c_str());
             CharLower(zExt);
             nPos = (long) sAudio.find(zExt);
             if (nPos) {
                if (SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) zTmp) > -1) {
                   nCount += 1;
                }
             }
          }
          if (FindNextFile(hFind, &fd) == false) { IsOk = 0; }
       }
       FindClose(hFind);
    }

    if (nCount) {
       if (nUseItem > nCount) { nUseItem = 1; }
       ComboSelectPlus(hCombo, nUseItem);
    }
}

void DetectPlugin (HWND hCombo, long nUseItem) {

    if (!hCombo) return;

    long nCount, nPos;
    HANDLE hFind;
    WIN32_FIND_DATAW fd;
    WCHAR zTmp[MAX_PATH];
    WCHAR zExt[8];
    wstring sExt;

    SendMessage(hCombo, CB_RESETCONTENT, 0, 0);

    wstring sSearch = g_sPluginPath; sSearch += L"*.dll";
    wcscpy_s(zTmp, (WCHAR*) sSearch.c_str());
    hFind = FindFirstFile(zTmp, &fd);
    nCount = 0;
    if (hFind != INVALID_HANDLE_VALUE) {
       int IsOk = -1;
       while (IsOk != 0) {
          if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
             sSearch = fd.cFileName;
             wcscpy_s(zTmp, (WCHAR*) sSearch.c_str());
             nPos = (long) sSearch.find_last_of(L"."); // Extract extension.
             sExt = sSearch.substr(nPos); sExt += L".";
             wcscpy_s(zExt, (WCHAR*) sExt.c_str());
             CharLower(zExt);
             sExt = zExt;
             if (!sExt.compare(L".dll.")) { // Check if the two strings are the same
                if (SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) zTmp) > -1) {
                    nCount += 1;
                    if ((_wcsicmp(zTmp, L"Hud_Beam.dll") == 0) && (nUseItem == 0)) { nUseItem = nCount; }
                }
             }
          }
          if (FindNextFile(hFind, &fd) == false) { IsOk = 0; }
       }
       FindClose(hFind);
    }

    if (nCount) {
       if (nUseItem > nCount) { nUseItem = 1; }
       ComboSelectPlus(hCombo, nUseItem);
    }
}

void ZWP_SizeMove() {
    RECT lpw;
    int x, y, w, h;
    HWND hWnd, hPopup;
    GetWindowRect(g_hMain, &lpw);
    x = lpw.left + skGetSystemMetrics(SK_DWM_LEFT);
    y = lpw.top + skGetSystemMetrics(SK_DWM_TOP);
    w = lpw.right - skGetSystemMetrics(SK_DWM_RIGHT) - x;
    h = lpw.bottom - skGetSystemMetrics(SK_DWM_BOTTOM) - y;

    // Use this to move the window in case of AERO shake
    // because setting the new location with SetWindowPos
    // may fail!
    hWnd = ZWP_Handle();
    if (hWnd) {
        hPopup = skGetDWMregion(g_hMain);
        if (hPopup == 0) { hPopup = g_hMain; }
   
        SetWindowPos(hWnd, GetWindow(hPopup, 2), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS);
        MoveWindow(hWnd, x, y, w, h, 0);
    }
}

long ZWP_Message(wstring wS) {
    string sMsg = ws2s(wS);
    char szText[512];
    strncpy_s(szText, sMsg.c_str(), sMsg.size() );
    long nRet = (long) SendMessageA(ZWP_Handle(), WM_SETTEXT, 0, (LPARAM) szText);
    return nRet;
}

HWND ZWP_Handle() {
    static HWND hZWP;
    if (hZWP == 0) {
       char zClass[] = "ZWALLPAPER";
       hZWP = FindWindowA(zClass, zClass);
       if (hZWP) {
          ZWP_SizeMove();
          string sMsg = "PARENT,";
          char szStr[12];
          sprintf_s(szStr, "% d", g_hMain);
          sMsg += szStr;
          sMsg += ",";
          sprintf_s(szStr, "% d", IDC_MAIN_WALLPAPER);
          sMsg += szStr;
          ZWP_Message(stringW(sMsg));
       }
    }
    return hZWP;
}

void ZWP_Play(wstring sAudio) {
    wstring sMsg = L"PLAY,"; sMsg += sAudio;
    ZWP_Message(sMsg);
}

void ZWP_Stop() {
    ZWP_Message(L"STOP");
}

void ZWP_Hide() {
    ShowWindow(ZWP_Handle(), SW_HIDE);
    ZWP_Stop();
}

void ZWP_Destroy() {
    ZWP_Message(L"DESTROY");
}

void ZWP_UsePlugin(wstring sPlugin) {
    wstring sCommand = L"PLUGIN,"; sCommand += sPlugin;
    ZWP_Message(sCommand);
}

void ZWP_Show(wstring sAudio) {
    RECT lpw;
    long x, y, w, h;
    HWND hWnd, hPopup;
    GetWindowRect(g_hMain, &lpw);
    x = lpw.left + skGetSystemMetrics(SK_DWM_LEFT);
    y = -2000;
    w = lpw.right - skGetSystemMetrics(SK_DWM_RIGHT) - x;
    h = lpw.bottom - skGetSystemMetrics(SK_DWM_BOTTOM) - y;

    // Use this to move the window in case of AERO shake
    // because setting the new location with SetWindowPos
    // may fail!
    hWnd = ZWP_Handle();
    hPopup = skGetDWMregion(g_hMain);
    if (hPopup == 0) { hPopup = g_hMain; }
    SetWindowPos(hWnd, GetWindow(hPopup, 2), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
    MoveWindow(hWnd, x, y, w, h, 0);

    ZWP_SizeMove();
    ZWP_Play(sAudio);
    ShowWindow(hWnd, SW_SHOW);
}

void UseThisZoom(long nPos) {
    if (g_nFocusID) {
       HWND hCtrl;
       float rZoomValue;

       rZoomValue = float (nPos * 0.001);
       if (rZoomValue != g_rWasZoom) {
          hCtrl = ZD_GetObjectParent(g_nFocusID);
          // Make sure to disable the crop rectangle if any
          if (ZI_GetToolCropStatus(hCtrl)) { ZI_DisableCropRectangle(hCtrl); }

          ZD_SetObjectScale(g_nFocusID, rZoomValue);
          ZI_UpdateWindow(hCtrl, FALSE);

       }
       g_rWasZoom = rZoomValue;
    }
}

void GDImageSetZoomRange(long bmW, long bmH, long &xSize, long &ySize) {
    RECT lpr = {0};
    long xPos = 0, yPos = 0;
    HWND hCtrl = 0;
    GetClientRect(g_hImageCtrl, &lpr);
    ZI_Iconise(bmW, bmH, lpr.right, lpr.bottom, xPos, yPos, xSize, ySize);
    hCtrl = GetDlgItem(g_hMain, IDC_MAIN_SLIDEZOOM);
    SendMessage(hCtrl, TBM_SETRANGE, 1, MAKELONG((int)((xSize / bmW) * 128), 1500));
}

void UseThisPhoto(WCHAR* sUsePhoto, long bReset) {

    RECT lpr = {0};
    HBITMAP hBitmap = 0;
    long nW = 0, nH = 0, nX = 0, nY = 0, nSizeX = 0, nSizeY = 0, nPosAngle = 0;
    float rAspect = 0.0f, rZoomValue = 0.0f;

    // Make sure to disable the crop rectangle if any
    if (ZI_GetToolCropStatus(g_hImageCtrl)) { ZI_DisableCropRectangle(g_hImageCtrl); }

    ZI_GetImageSizeFromFile(sUsePhoto, g_nTrueWidth, g_nTrueHeight);
    nW = max(g_nTrueWidth, g_nTrueHeight);
    if (nW > 1024) { nW = 1024; }
    hBitmap = ZI_FitBitmapFromFile(sUsePhoto, nW, nW);
    ZI_GetBitmapSize(hBitmap, nW, nH);


    if (hBitmap) {
       g_nUseWidth = nW; g_nUseHeight = nH;

       // Compute range based on the image size
       GDImageSetZoomRange(g_nUseWidth, g_nUseHeight, nSizeX, nSizeY);

       GetClientRect(g_hImageCtrl, &lpr);
       ZI_Iconise(g_nTrueWidth, g_nTrueHeight, lpr.right, lpr.bottom, nX, nY, nW, nH);
       if (nW > nH) {
          rAspect = float (nW / nH); }
       else {
          rAspect = 1;
       }

       rZoomValue = float (nSizeX / (g_nUseWidth / rAspect));
       SendMessage(GetDlgItem(g_hMain, IDC_MAIN_SLIDEZOOM), TBM_SETPOS, 1, (LPARAM)(rZoomValue * 1000));

       GetClientRect(g_hImageCtrl, &lpr);
       nX = (lpr.right - g_nUseWidth) / 2;
       nY = (lpr.bottom - g_nUseHeight) / 2;

       ZD_DrawBitmapToCtrl(g_hImageCtrl, nX, nY, hBitmap, ZD_ColorARGB(255, 0), ID_PHOTO, ZS_HIDDEN); // ZS_VISIBLE)
       ZD_SetObjectScale(ID_PHOTO, rZoomValue);

       nPosAngle = skGaugeGetPos(GetDlgItem(g_hMain, IDC_MAIN_KNOBBIG));
       ZD_SetObjectAngle(ID_PHOTO, nPosAngle, FALSE);
       ZD_SetObjectAnchorMode(ID_PHOTO, ANCHOR_CENTER);

       SetFocus(g_hImageCtrl);
       ZI_SetObjectFocusID(ID_PHOTO);
       g_nFocusID = ID_PHOTO;

       ZD_SetObjectVisibility(ID_PHOTO, ZS_VISIBLE);
       ZI_UpdateWindow(g_hImageCtrl, 0);
    }
}

void UseThisAnimation(WCHAR* sUsePhoto, long ID_OBJECT) {

    RECT lpr = {0};
    HBITMAP hBitmap = 0;
    long nW = 0, nH = 0, nX = 0, nY = 0, nSizeX = 0, nSizeY = 0, nPosAngle = 0, nReserved = 0, nFrameCount = 0;
    float rAspect = 0.0f, rZoomValue = 0.0f;

    // Make sure to disable the crop rectangle if any
    if (ZI_GetToolCropStatus(g_hImageCtrl)) { ZI_DisableCropRectangle(g_hImageCtrl); }

    hBitmap = skSkiToDib (sUsePhoto, nReserved);
    if (hBitmap) {
       ZI_GetBitmapSize(hBitmap, nW, nH);
       nFrameCount = nW / nH; nW = nH;
       g_nUseWidth = nW; g_nUseHeight = nH;

       // Compute range based on the image size
       GDImageSetZoomRange(g_nUseWidth, g_nUseHeight, nSizeX, nSizeY);

       GetClientRect(g_hImageCtrl, &lpr);
       ZI_Iconise(g_nTrueWidth, g_nTrueHeight, lpr.right, lpr.bottom, nX, nY, nW, nH);
       if (nW > nH) {
          rAspect = float (nW / nH); }
       else {
          rAspect = 1;
       }

       rZoomValue = float (nSizeX / (g_nUseWidth / rAspect));
       SendMessage(GetDlgItem(g_hMain, IDC_MAIN_SLIDEZOOM), TBM_SETPOS, 1, (LPARAM)(rZoomValue * 1000));

       GetClientRect(g_hImageCtrl, &lpr);
       nX = (lpr.right - g_nUseWidth) / 2;
       nY = (lpr.bottom - g_nUseHeight) / 2;

       ZD_DrawBitmapToCtrl(g_hImageCtrl, nX, nY, hBitmap, ZD_ColorARGB(255, 0), ID_OBJECT, ZS_HIDDEN); // ZS_VISIBLE)
       ZD_SetObjectFrameCount(ID_OBJECT, (BYTE) nFrameCount);
       ZD_SetObjectFrameToUse(ID_OBJECT, 1, FALSE);
       ZD_SetObjectScale(ID_OBJECT, rZoomValue);

       nPosAngle = skGaugeGetPos(GetDlgItem(g_hMain, IDC_MAIN_KNOBBIG));
       ZD_SetObjectAngle(ID_OBJECT, nPosAngle, FALSE);
       ZD_SetObjectAnchorMode(ID_OBJECT, ANCHOR_CENTER);

       SetFocus(g_hImageCtrl);
       ZI_SetObjectFocusID(ID_OBJECT);
       g_nFocusID = ID_OBJECT;

       ZD_SetObjectVisibility(ID_OBJECT, ZS_VISIBLE);
       ZI_UpdateWindow(g_hImageCtrl, 0);
    }
}

// Main winproc
LRESULT CALLBACK WndProc(IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) {

    HWND hPopup = 0, hDW = 0, hCtrl = 0;
    long wmId = 0, wmEvent = 0, nRet = 0, nPos = 0;
    wstring sUseFile, sResource;
    WCHAR szFile[MAX_PATH] = {0};
    NMHDR* pNMHDR;
    PAINTSTRUCT ps = {0}; HDC hdc = 0;
    HDROP hfInfo = {0};

    if (uMsg == WM_ZWPNOTIFICATION) {
        switch (wParam) {
        case NM_AUDIOCOMPLETION:
             // Uncheck VisualPlugin
             SendMessage(GetDlgItem(hWnd, IDC_MAIN_PLUGIN), BM_SETCHECK, BST_UNCHECKED, 0);
             ZWP_Hide();
             hPopup = skGetDWMregion(hWnd);
             if (hPopup) {
                SetWindowPos(hPopup, GetWindow(hWnd, 2), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
                SetFocus(hWnd);
             }
             break;
        }
        return 0;
    }

    switch (uMsg) {

    case WM_DROPFILES:
         hfInfo = HDROP(wParam);
         nRet = DragQueryFileA(hfInfo, 0xFFFFFFFF, NULL, 0);
         if (nRet > 0) {
            nRet = DragQueryFile(hfInfo, 0, szFile, MAX_PATH);
            if (nRet) {
               SendMessage(GetDlgItem(hWnd, IDC_MAIN_PLUGIN), BM_SETCHECK, BST_CHECKED, 0);
               hPopup = skGetDWMregion(hWnd);
               if (hPopup) { ShowWindow(hPopup, SW_HIDE); }
               ZWP_Show(szFile);
            }
         }
         DragFinish(hfInfo);
         SetForegroundWindow(hWnd);
         break;

    case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
         // TODO: process here the WM_PAINT message...
         EndPaint(hWnd, &ps);
         return 0;

    case WM_NOTIFY:
         pNMHDR = (NMHDR*) lParam;
         // Assign the new rotation angle to the sprite image.
         nPos = pNMHDR->code;
         switch (pNMHDR->idFrom) { 

         case IDC_MAIN_KNOBBIG:
              ZD_SetObjectAngle(g_nFocusID, nPos, TRUE);
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBLEFT), nPos, TRUE);
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBRIGHT), nPos, TRUE);
              break;
         case IDC_MAIN_KNOBLEFT:
              ZD_SetObjectAngle(g_nFocusID, nPos, TRUE);
//g_nDelay = min(max((long) (nPos / 4.5f), 0), 80);
//zTrace(STRL$(g_nDelay));
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBBIG), nPos, TRUE);
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBRIGHT), nPos, TRUE);
              break;
         case IDC_MAIN_KNOBRIGHT:
              ZD_SetObjectAngle(g_nFocusID, nPos, TRUE);
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBBIG), nPos, TRUE);
              skGaugeSetPos(GetDlgItem(hWnd, IDC_MAIN_KNOBLEFT), nPos, TRUE);
              break;
         }
         return 0;

    case WM_SIZE:
    case WM_MOVE:
    case WM_WINDOWPOSCHANGED:
    case WM_IME_NOTIFY:
         if (ZWP_Handle()) {
            ZWP_SizeMove();
         }
         break;

    case WM_COMMAND:
         wmId    = LOWORD(wParam);
         wmEvent = HIWORD(wParam);

         // Process menu command
         switch (wmId) {

         case IDC_MAIN_LOADIMAGE:
              hDW = skCreateDW(hWnd);
              wcscpy_s(szFile, ZI_LoadDialog(hWnd));
              skDestroyDW(hDW);

              if (wcslen(szFile)) {
                  UseThisPhoto(szFile, 0);
              }
              break;

         case IDC_MAIN_CHECKBOX:
              nRet = (long) SendMessage(GetDlgItem(hWnd, IDC_MAIN_CHECKBOX), BM_GETCHECK, 0, 0);
              if (nRet == BST_CHECKED) {
                 ZI_UseWinLIFTbackground(g_hImageCtrl, FALSE, TRUE); }
              else {
                 ZI_UseWinLIFTbackground(g_hImageCtrl, TRUE, TRUE);
              }
              SetFocus(g_hImageCtrl);
              break;

         case IDC_MAIN_PLUGIN:
              nRet = (long) SendMessage(GetDlgItem(hWnd, IDC_MAIN_PLUGIN), BM_GETCHECK, 0, 0);
              if (nRet == BST_CHECKED) {
                 hCtrl = GetDlgItem(hWnd, IDC_CB_AUDIO);
                 SendMessage(hCtrl, CB_GETLBTEXT, SendMessage(hCtrl, CB_GETCURSEL, 0, 0), (LPARAM) szFile);
                 hPopup = skGetDWMregion(hWnd);
                 if (hPopup) { ShowWindow(hPopup, SW_HIDE); }
                 sUseFile = g_sAudioPath; sUseFile += (WCHAR*) szFile;
                 wcscpy_s(szFile, (WCHAR*) sUseFile.c_str());
                 ZWP_Show(szFile); }
              else {
                 hPopup = skGetDWMregion(hWnd);
                 if (hPopup) { ShowWindow(hPopup, SW_SHOW); }
                 ZWP_Hide();
              }
              SetFocus(g_hImageCtrl);
              break;

         case IDC_CB_PLUGIN:
              if (wmEvent == CBN_SELENDOK) {
                 hCtrl = GetDlgItem(hWnd, IDC_CB_PLUGIN);
                 SendMessage(hCtrl, CB_GETLBTEXT, SendMessage(hCtrl, CB_GETCURSEL, 0, 0), (LPARAM) szFile);


                 if (_wcsicmp(szFile, L"Hud_Matrix.dll") == 0) {
                     sUseFile = g_sResourcePath; sUseFile += L"dgirl256.ski"; }
                 else if (_wcsicmp(szFile, L"Hud_Attractor.dll") == 0) {
                     sUseFile = g_sResourcePath; sUseFile += L"attractor.ski"; }
                 else if (_wcsicmp(szFile, L"Hud_Bubble.dll") == 0) {
                     sUseFile = g_sResourcePath; sUseFile += L"bubble.ski"; }
                 else if (_wcsicmp(szFile, L"Hud_Hal.dll") == 0) {
                     sUseFile = g_sResourcePath; sUseFile += L"hal.ski"; }
                 else {
                     sUseFile = g_sResourcePath; sUseFile += L"bighead.ski";
                 }
                 UseThisAnimation((WCHAR*) sUseFile.c_str(), ID_SPIN03);


                 sUseFile = g_sPluginPath; sUseFile += szFile;
                 wcscpy_s(szFile, (WCHAR*) sUseFile.c_str());
                 ZWP_UsePlugin(szFile);

                 SetFocus(g_hImageCtrl);
              }
              break;

         case IDC_CB_AUDIO:
              if (wmEvent == CBN_SELENDOK) {
                 nRet = (long) SendMessage(GetDlgItem(hWnd, IDC_MAIN_PLUGIN), BM_GETCHECK, 0, 0);
                 if (nRet == BST_CHECKED) {
                    hCtrl = GetDlgItem(hWnd, IDC_CB_AUDIO);
                    SendMessage(hCtrl, CB_GETLBTEXT, SendMessage(hCtrl, CB_GETCURSEL, 0, 0), (LPARAM) szFile);
                    sUseFile = g_sAudioPath; sUseFile += szFile;
                    wcscpy_s(szFile, (WCHAR*) sUseFile.c_str());
                    ZWP_Play(szFile);
                 }
                 SetFocus(g_hImageCtrl);
              }
              break;

         }
         return 0;

    case WM_VSCROLL:
         nRet = GetDlgCtrlID((HWND) lParam);
         if (nRet == IDC_MAIN_SLIDEZOOM) {
            UseThisZoom((long) SendMessage((HWND) lParam, TBM_GETPOS, 0, 0)); // Do not use nPosition, because it could be NULL.
         }
         break;

    case WM_CLOSE:
         hPopup = skGetDWMregion(hWnd);
         // Hide DWMregion if any.
         if (hPopup) { MoveWindow(hPopup, 0, 0, 0, 0, 1); }
         break;

    case WM_DESTROY:
         DragAcceptFiles(hWnd, 0);
         ZWP_Destroy();
         PostQuitMessage(0);
         return 0;
    }

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

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

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // Check if ZWP is already running.
    char zClass[] = "ZWALLPAPER";
    HWND hZWP = FindWindowA(zClass, zClass);

    // Important: we use RegisterWindowMessage to communicate with ZWP's plugins.
    WM_ZWPNOTIFICATION = RegisterWindowMessageA("ZWPnotification");

    // Declaration of local variables
    MSG msg;
    long nRet = 0;
    long IsInitialized = 0;
    WNDCLASSEX wcx;
    WCHAR szWindowClass[] = L"ZHUDPLUS";
    WCHAR szTitle[20] = {0};
    if (sizeof(LONG_PTR) == 8) {
        wcscpy_s(szTitle, L"HUD window 64-bit");}
    else {
        wcscpy_s(szTitle, L"HUD window 32-bit");
    }
    WCHAR szFullpathToFile[MAX_PATH] = {0};

    // Register the main window class
    wcx.cbSize = sizeof(wcx);
    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

       long w = MyWindowWidth;
       long h = MyWindowHeight;
       long x = max((GetSystemMetrics(SM_CXSCREEN) - w) / 2, 0);
       long y = max((GetSystemMetrics(SM_CYSCREEN) - h) / 2, 0);

       DWORD dwStyle = WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
                       WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // | WS_VISIBLE

       g_hMain    = CreateWindowEx(
                    WS_EX_ACCEPTFILES,              // Optional window styles.
                    szWindowClass,                  // Window class
                    szTitle,                        // Window text
                    dwStyle,                        // Window style

                    // Size and position
                    x, -2000, w, h,

                    NULL,       // Parent window
                    NULL,       // Menu
                    hInstance,  // Instance handle
                    NULL        // Additional application data
                    );

       if (g_hMain) {
           WCHAR szExePath[MAX_PATH] = {0}; wcscpy_s(szExePath, (WCHAR*) EXEpath().c_str());
           wstring wS = (WCHAR*) szExePath; wS += L"ZWP.exe";
           WCHAR szRunProg[MAX_PATH] = {0}; wcscpy_s(szRunProg, (WCHAR*) wS.c_str());
           skTerminateProcess(szRunProg); // Kill any previous instance of ZWP.exe if any...

           g_hImageCtrl = CreateWindowEx(0, GDImageClassName, NULL,
                                         WS_CHILD | WS_VISIBLE,
                                         78, 40, 628, 432,
                                         g_hMain, (HMENU) IDC_MAIN_GDIMAGE,
                                         hInstance, NULL);

           HWND hCtrl   = CreateWindowEx(0, L"MSCTLS_TRACKBAR32", NULL,
                                         WS_CHILD | WS_VISIBLE | WS_TABSTOP | TBS_VERT | TBS_BOTTOM | TBS_AUTOTICKS,
                                         728, 40, 32, 432,
                                         g_hMain, (HMENU) IDC_MAIN_SLIDEZOOM,
                                         hInstance, NULL);

           g_sResourcePath = (WCHAR*) szExePath; g_sResourcePath += L"Resource\\";
           g_sAudioPath = (WCHAR*) szExePath; g_sAudioPath += L"Audio\\";
           g_sPluginPath = (WCHAR*) szExePath; g_sPluginPath += L"BBPlugin\\";

           wstring SkinTheme = (WCHAR*) szExePath; SkinTheme += L"Naavi.sks";
           if (skInitEngine ((WCHAR*) SkinTheme.c_str(), L"")) {

               skSkinWindow(g_hMain, L"Dock|Undock|Minimize|Maximize|Restore|Close");

               // Anchor the SLIDEZOOM trackbar
               skSetAnchorCtrl(hCtrl, ANCHOR_HEIGHT_RIGHT);

               hCtrl = CreateWindowEx(0, L"BUTTON", L"Transparent HUD mode",
                                      WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX,
                                      500, 542, 200, 16,
                                      g_hMain, (HMENU) IDC_MAIN_CHECKBOX,
                                      hInstance, NULL);
               skSkinChildCtrl(hCtrl, 0), skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               ZI_UseWinLIFTbackground(g_hImageCtrl, TRUE, FALSE);

               hCtrl = CreateWindowEx(0, L"COMBOBOX", NULL,
                                      WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS,
                                      127, 542-49, 150, 164,
                                      g_hMain, (HMENU) IDC_CB_AUDIO,
                                      hInstance, NULL);
               DetectAudio(hCtrl, 1);
               skSkinChildCtrl(hCtrl, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);

               hCtrl = CreateWindowEx(0, L"COMBOBOX", NULL,
                                      WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | CBS_HASSTRINGS,
                                      127, 542-24, 150, 164,
                                      g_hMain, (HMENU) IDC_CB_PLUGIN,
                                      hInstance, NULL);
               DetectPlugin(hCtrl, 0);
               skSkinChildCtrl(hCtrl, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               SendMessage(hCtrl, CB_GETLBTEXT, SendMessage(hCtrl, CB_GETCURSEL, 0, 0), (LPARAM) szFullpathToFile);

               wS = g_sPluginPath; wS += (WCHAR*) szFullpathToFile;
               WCHAR szPlaythis[MAX_PATH] = {0}; wcscpy_s(szPlaythis, (WCHAR*) wS.c_str());

               // Start the background plugin player.
               if (hZWP == 0) {
                   ShellExecuteA(0, "open", ws2s(szRunProg).c_str(), ws2s(szPlaythis).c_str(), ws2s(szExePath).c_str(), SW_SHOWNOACTIVATE);
               }

               hCtrl = CreateWindowEx(0, L"BUTTON", L"Play visual plugin",
                                      WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX,
                                      127, 542, 150, 16,
                                      g_hMain, (HMENU) IDC_MAIN_PLUGIN,
                                      hInstance,
                                      NULL);
               skSkinChildCtrl(hCtrl, 0); skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               skCreateToolTip(hCtrl, L"Enable/disable visual plugin");

               // Add a clock control.
               wstring sResource = g_sResourcePath; sResource += L"Clock_09_92.png";
               hCtrl = skClockCtrl(g_hMain, (WCHAR*) sResource.c_str(), 4, 476, 0, 0, IDC_MAIN_CLOCK, 0x7FCB0000, 0x7F8F8F8F, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_BOTTOM);          // Anchor control
               skCreateToolTip(hCtrl, L"WinLIFT clock widget"); // Add tooltip.

               // Add a 5-state button image.
               sResource = g_sResourcePath; sResource += L"SelectImage.png";
               hCtrl = skButtonImage(g_hMain, (WCHAR*) sResource.c_str(), 780 - 58, 498, IDC_MAIN_LOADIMAGE, 5);
               skSetAnchorCtrl(hCtrl, ANCHOR_BOTTOM_RIGHT);
               skCreateToolTip(hCtrl, L"WinLIFT ButtonImage");

               // Add two circular slider gauges.
               sResource = g_sResourcePath; sResource += L"BTN_Gauge01.png";
               hCtrl = skKnobGauge(g_hMain, (WCHAR*) sResource.c_str(), 303, 527, 0, 0, IDC_MAIN_KNOBLEFT, 0, 0, 0, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               skCreateToolTip(hCtrl, L"WinLIFT KnobGauge");
               hCtrl = skKnobGauge(g_hMain, (WCHAR*) sResource.c_str(), 436, 527, 0, 0, IDC_MAIN_KNOBRIGHT, 0, 0, 0, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               skCreateToolTip(hCtrl, L"WinLIFT KnobGauge");

               // Add a circular slider gauge.
               sResource = g_sResourcePath; sResource += L"BTN_Gauge02.png";
               hCtrl = skKnobGauge(g_hMain, (WCHAR*) sResource.c_str(), 344, 476, 0, 0, IDC_MAIN_KNOBBIG, 0, 0, 0, 0);
               skSetAnchorCtrl(hCtrl, ANCHOR_CENTER_HORZ_BOTTOM);
               skCreateToolTip(hCtrl, L"WinLIFT KnobGauge");

               if (g_hImageCtrl) {
                   RECT lpw;
                   POINT p;
                   GetWindowRect(g_hImageCtrl, &lpw);
                   p.x = lpw.left, p.y = lpw.top;
                   ScreenToClient (g_hMain, &p);
                   skBorder(g_hImageCtrl, p.x - 1, p.y - 1, lpw.right - lpw.left + 2, lpw.bottom - lpw.top + 2, 0, 1);
                   // Anchor the GDImage control.
                   skSetAnchorCtrl(g_hImageCtrl, ANCHOR_HEIGHT_WIDTH);

                   // Compute the good range to use with the zoom slider.
                   long imgW = 0, imgH = 0, xP = 0, yP = 0, xS = 0, yS = 0;
                   ZI_GetImageSizeFromControl(g_hImageCtrl, imgW, imgH);

                   ZI_Iconise(imgW, imgH, lpw.right - lpw.left, lpw.bottom - lpw.top, xP, yP, xS, yS);
                   if (imgW) {
                       hCtrl = GetDlgItem(g_hMain, IDC_MAIN_SLIDEZOOM);
                       SendMessage(hCtrl, TBM_SETPAGESIZE, 0, 1);
                       SendMessage(hCtrl, TBM_SETLINESIZE, 0, 1);
                       SendMessage(hCtrl, TBM_SETTICFREQ, 0, 1);
                       SendMessage(hCtrl, TBM_SETRANGE, 1, MAKELONG( 1, imgW));
                       SendMessage(hCtrl, TBM_SETPOS, 1, xS);
                   }

                   // Start with the default picture.
                   //sResource = g_sResourcePath; sResource += L"Naavi.png";
                   //UseThisPhoto((WCHAR*) sResource.c_str(), 0);

                   // Add a transparent logo on the top right corner.
                   sResource = g_sResourcePath; sResource += L"GDImage.png";
                   // Load image and retrieve the width and height of its bitmap.
                   HBITMAP hBitmap = ZI_CreateBitmapFromFile((WCHAR*) sResource.c_str(), imgW, imgH);
                   // Use the new hBitmap to create a sprite image on the top right corner.
                   ZD_DrawBitmapToCtrl(g_hImageCtrl, (lpw.right - lpw.left) - (imgW + 10), 10, hBitmap, ZD_ColorARGB(255, 0), ID_LOGO, ZS_VISIBLE);
                   // Anchor the logo to the top right corner.
                   ZD_SetObjectAnchorMode(ID_LOGO, ANCHOR_RIGHT);
                   // Lock and disable the sprite image.
                   ZD_SetObjectLocked(ID_LOGO, TRUE);
                         

                   // The animated sprite.
                   sResource = g_sResourcePath; sResource += L"sparkling.ski";
                   long nReserved = 0;
                   hBitmap = skSkiToDib ((WCHAR*) sResource.c_str(), nReserved);
                   ZI_GetBitmapSize(hBitmap, imgW, imgH);
                   //ZD_DrawBitmapToCtrl(g_hImageCtrl, (lpw.right - lpw.left) - (imgW + 10), 128, hBitmap, ZD_ColorARGB(255, 0), ID_SPIN01, ZS_VISIBLE);
                   ZD_DrawBitmapToCtrl(g_hImageCtrl, (lpw.right - lpw.left) - (imgH - 40), -55, hBitmap, ZD_ColorARGB(255, 0), ID_SPIN01, ZS_VISIBLE);
                   ZD_SetObjectFrameCount(ID_SPIN01, (BYTE) (imgW / imgH));
                   ZD_SetObjectFrameToUse(ID_SPIN01, 1, FALSE);
//                 ZD_SetObjectZorder(ID_SPIN01, ZD_ORDER_BOTTOM); // Change Z-ORDER
                   // Set anchor mode
                   ZD_SetObjectAnchorMode(ID_SPIN01, ANCHOR_RIGHT);

                   // The animated sprite.
                   sResource = g_sResourcePath; sResource += L"triangle.ski";
                   nReserved = 0;
                   hBitmap = skSkiToDib ((WCHAR*) sResource.c_str(), nReserved);
                   ZI_GetBitmapSize(hBitmap, imgW, imgH);
                   ZD_DrawBitmapToCtrl(g_hImageCtrl, 0, (lpw.bottom - lpw.top) - imgH, hBitmap, ZD_ColorARGB(255, 0), ID_SPIN02, ZS_VISIBLE);
                   ZD_SetObjectFrameCount(ID_SPIN02, (BYTE) (imgW / imgH));
                   ZD_SetObjectFrameToUse(ID_SPIN02, 1, FALSE);
//                 ZD_SetObjectZorder(ID_SPIN02, ZD_ORDER_BOTTOM); // Change Z-ORDER
                   // Set anchor mode
                   ZD_SetObjectAnchorMode(ID_SPIN02, ANCHOR_BOTTOM);


                   // The animated sprite.
                   sResource = g_sResourcePath; sResource += L"bighead.ski";
                   UseThisAnimation((WCHAR*) sResource.c_str(), ID_SPIN03);
//                   nReserved = 0;
//                   hBitmap = skSkiToDib ((WCHAR*) sResource.c_str(), nReserved);
//                   ZI_GetBitmapSize(hBitmap, imgW, imgH);
//                   ZD_DrawBitmapToCtrl(g_hImageCtrl, -40, -30, hBitmap, ZD_ColorARGB(255, 0), ID_SPIN03, ZS_VISIBLE);
//                   ZD_SetObjectFrameCount(ID_SPIN03, (BYTE) (imgW / imgH));
//                   ZD_SetObjectFrameToUse(ID_SPIN03, 1, FALSE);
////                 ZD_SetObjectZorder(ID_SPIN03, ZD_ORDER_BOTTOM); // Change Z-ORDER
//                   // Set anchor mode
//                   ZD_SetObjectAnchorMode(ID_SPIN03, ANCHOR_LEFT);

               }
           }

           ShowWindow(g_hMain, SW_SHOW);

           // Resize the main window to 16/9.
           RECT lpw;
           GetWindowRect(g_hMain, &lpw);
           h = lpw.bottom - lpw.top; w = (long) (h * 1.77f); // Turn it to wide screen.
           x = max((GetSystemMetrics(SM_CXSCREEN) - w) / 2, 0);
           //MoveWindow(g_hMain, x, lpw.top, w, h, 0);

           //// Create a fall down effect animation.
           //ShowWindow(g_hImageCtrl, 0);
           //dwStyle = RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME;
           //long k;
           //for (k = -h ; k < 0 ; k += 8 ) {
           //     MoveWindow(g_hMain, x, k, w, h, 0);
           //}
           //for (k = 0; k <= y; k += 8) {
           //     MoveWindow(g_hMain, x, k, w, h, 0);
           //     RedrawWindow(g_hMain, NULL, NULL, dwStyle);
           //}
           y = max((GetSystemMetrics(SM_CYSCREEN) - h) / 2, 0);
           MoveWindow(g_hMain, x, y, w, h, 0);
           ShowWindow(g_hImageCtrl, SW_SHOW);

           StartAnimation(TIMER_DELAY);

           // Main message loop
           while (GetMessage(&msg, NULL, 0, 0)) {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
           }
           nRet = (long) msg.wParam;
       }

    }
    return nRet;
}


The full VS2010 project is available on request.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

Here are five screen shots of HUD window playing different plugins.

Tip: If you have the song "Scatterlings of Africa" (by Johny Clegg), then try it with the Hud_Matrix plugin, the animation is almost using the correct tempo.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Theo Gottwald

While id o not share your musicv taste, your graphics is TOP as always.
Funny to have it just in a PowerBasic Forum, because regular PB is just at the end of the scale in Graphics Capabilities :-)


Patrice Terrier

#7
QuoteFunny to have it just in a PowerBasic Forum
A PowerBASIC forum, are you sure  :)

Time to move on Theo  ;D

About the music taste, you can just dragg the one you want  8)
And about PB's graphic i would rather say {bottom} of the scale, but that is not the purpose of a compiler  ;)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#8
QuoteBottom of the scale should be right as long as the compiler is able to work in conjunction with sophisticated graphics libraries
Or as long as it allows us to create sophisticated graphics libraries with it :)

I always thought that a compiler should do what it does best: create machine code, instead of trying to turn into a swiss army knife.

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

Brice Manuel

Quote from: Patrice Terrier on October 06, 2013, 02:30:31 PMI always thought that a compiler should do what it does best: create machine code, instead of trying to turn into a swiss army knife.

I do not disagree, but that only applies to compilers, not programming languages.  PowerBASIC was first and foremost a programming language.

Patrice Terrier

#10
QuotePowerBASIC was first and foremost a programming language.

No, after the fiasco of PBDK, the first Windows version was PB/DLL which purpose was to create DLL(s), and dixit the very arrogant advertisement of the time, "kills VB's bug dead", since that time i always used it for that feature, because for everything else, it was years behind the other programming tools i am using.

I even never used PB/EDIT but always rely on my faithfull UltraEdit...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Brice Manuel

QuoteNo, after the fiasco of PBDK, the first Windows version was PB/DLL which purpose was to create DLL(s), and dixit the very arrogant advertisement of the time, "kills VB's bug dead", since that time i always used it for that feature, because for everything else, it was years behind the other programming tools i am using.

Although limited, the first Windows version was still a programming language.  You can't help but laugh at releasing a programming language for Windows that could not actually create programs for Windows.  Apparently it took Bob some time to learn and understand Windows enough to release a more functional version of PowerBASIC for Windows.  PB has always been WAY behind industry standards.  The main thing it had going for it was stability, speed and size.  Sadly these three things dropped off a bit in 9 and 10. 


QuoteI even never used PB/EDIT but always rely on my faithfull UltraEdit...

Although I like Ultra Edit, I always used Jose's IDEs for PB.  What PB provides is an embarrassment.

Patrice Terrier

#12
HUDplus64.zip has been updated with WinLIFT64.dll and GDImage64.dll compiled with the /MT switch, to get rid of the C++ run-time.

Thanks to Mike Stefanik, who reminds me that one, that was already in my pitfall list (Alzheimer is coming).  :-[

The link to the ZIP file is in the first post of this thread.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

James C. Fuller

Patrice,
  No dll's in the zip just the lib files.
Where to get the dll's
James

Patrice Terrier

James--

Due to size of the ZIP file it couldn't be attached to the first post of this thread, you have to download it from my server, there.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com