首页 > 其他分享 >频谱模拟

频谱模拟

时间:2023-02-15 11:25:12浏览次数:28  
标签:频谱 Draw wc int hWnd hdc NULL 模拟

#include <Windows.h>

#include <stdlib.h>

#include <vector>
#include <thread>
#include <mutex>
using namespace std;

enum {
    SPECTRUM_DATA_CNT = 63,
};

struct SDisplay {
    int            Width;
    int            Height;
    HDC            OffScreenDC;    
    HBITMAP        OffScreenBMP;
    HBRUSH        BlackBrush;
    HBRUSH        WhiteBrush;
};

struct SSpectrum {
    uint8_t        Current[SPECTRUM_DATA_CNT];
    uint8_t        Draw[SPECTRUM_DATA_CNT];
    recursive_mutex Mutex;
};

static struct {
    SDisplay    Display;
    SSpectrum    Spectrum;
} _G;

static void _DoPaint() {
    SDisplay& D = _G.Display;
    HDC& hdc = D.OffScreenDC;
    int w = D.Width;
    int h = D.Height;
    // uint8_t 
    
    int col_w = w / SPECTRUM_DATA_CNT - 2;
    SelectObject(hdc, D.BlackBrush);
    Rectangle(hdc, 0, 0, w, h);

    SSpectrum& S = _G.Spectrum;
    unique_lock<recursive_mutex> lock(S.Mutex);
    SelectObject(hdc, D.WhiteBrush);
    for (int i = 0; i < SPECTRUM_DATA_CNT; i++) {
        int x = i * w / SPECTRUM_DATA_CNT;
        int y = h - S.Draw[i] * h / 256;
        Rectangle(hdc, x, y, x + col_w, h);
    }
}

static void _OnPaint(HWND hWnd) {
    PAINTSTRUCT ps;
    BeginPaint(hWnd, &ps);

    RECT rc;
    GetClientRect(hWnd, &rc);
    int w = rc.right - rc.left;
    int h = rc.bottom - rc.top;

    SDisplay& d = _G.Display;
    HDC& hdc = d.OffScreenDC;
    HBITMAP& hbmp = d.OffScreenBMP;
    if (d.Width != w || d.Height != h) {
        d.Width = w;
        d.Height = h;        
        if (hdc == NULL) {
            hdc = CreateCompatibleDC(ps.hdc);
        }
        HBITMAP newBmp = CreateCompatibleBitmap(hdc, w, h);
        HBITMAP oldBmp = (HBITMAP)SelectObject(hdc, newBmp);
        if (hbmp && hbmp == oldBmp) {
            DeleteObject(hbmp);
        }
        hbmp = newBmp;
    }

    _DoPaint();

    BitBlt(ps.hdc, 0, 0, w, h, hdc, 0, 0, SRCCOPY);
    EndPaint(hWnd, &ps);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_PAINT:
        _OnPaint(hWnd);
        printf("WM_PAINT\n");
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

static const wchar_t* _GetWindowClassName() {
    return L"SpectrumWindow";
}

static void _InitWindowClass() {
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpszClassName = _GetWindowClassName();
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&wc);
}

static void _RandomSpectrum() {
    SSpectrum& S = _G.Spectrum;
    unique_lock<recursive_mutex> lock(S.Mutex);
    for (int i = 0; i < SPECTRUM_DATA_CNT; i++) {        
        S.Current[i] = rand() % 256;
        if (S.Draw[i] > S.Current[i]) {
            uint8_t d = S.Draw[i] - S.Current[i];
            if (d > 10) {
                d = 10;
            }
            S.Draw[i] -= d;
        }
        else if (S.Draw[i] < S.Current[i]) {
            uint8_t d = S.Current[i] - S.Draw[i];
            if (d > 10) {
                d = 10;
            }
            S.Draw[i] += d;
        }
    }
}

int main() {
    _InitWindowClass();

    _G.Display.BlackBrush = CreateSolidBrush(RGB(0, 0, 0));
    _G.Display.WhiteBrush = CreateSolidBrush(RGB(255, 255, 255));

    HWND hWnd = CreateWindow(_GetWindowClassName(), L"Spectrum", WS_OVERLAPPEDWINDOW,
        0, 0, 1024, 600, NULL, NULL, GetModuleHandle(NULL), NULL);
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    thread([hWnd] {
        for (int i = 0; i < 40*60; i++) {
            this_thread::sleep_for(chrono::milliseconds(25));
            _RandomSpectrum();
            InvalidateRect(hWnd, NULL, FALSE);
        }
    }).detach();

    MSG msg = { 0 };
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

标签:频谱,Draw,wc,int,hWnd,hdc,NULL,模拟
From: https://www.cnblogs.com/kehuadong/p/17122089.html

相关文章

  • 河北稳控科技工程监测多通道振弦模拟信号采集仪VTN参数修改!
    工程监测多通道振弦模拟信号采集仪VTN参数修改 1使用按键修改参数使用按键修改某个参数的方法如下:(1)在系统参数查看页面(PXX页面),按【SWITCH】或【SETTING】按键切换到......
  • 2.11 模拟赛
    A.小澳的方阵题面描述小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局。他努力钻研,发现秦始皇布置兵马俑是有一......
  • JMeter java模拟多用户高并发请求测试(json,form表单)
     1.情景展示在实际开发过程中,需要进行测试的时候,往往需要进行压力测试,或者高并发情况下,同时对一张表数据进行修改、读取操作,程序会不会出现多个用户取出的数据一致,或者......
  • 工程监测多通道振弦模拟信号采集仪VTN数据查看
    工程监测多通道振弦模拟信号采集仪VTN数据查看 通过按键操作,可使数码管显示不同类别的实时数据和运行参数,数据名称数码管显示3位符号,第一位为字母,表示当前正在查看的......
  • 蓝桥杯模拟赛 4
    P8780[蓝桥杯2022省B]刷题统计P8800[蓝桥杯2022国B]卡牌P8778[蓝桥杯2022省A]数的拆分P8808[蓝桥杯2022国C]斐波那契数组P8786[蓝桥杯2022省B......
  • 「考试总结」2023-02-13 联合省选模拟赛 – Day1
    爆搜$\texttt{(dfs)}$$\texttt{Statement}$给定一个$n$个点$m$条边的简单无向图,你需要对所有匹配$S$,把$c^{|S|}$求和,其中$|S|$是匹配......
  • 利用反射和代理简单模拟mybatis实现简单的CRUD
    利用反射接口做java数据库操作今天突发奇想,好像一些基本的CRUD操作路数都是一样的,又想到mybatis中的操作,便想着简单的模拟一下。随便写写,就当练习反射了。Dao接口类:这......
  • 2023-02-13 Android studio打包apk到手机上(模拟器也一样)运行时闪退
    环境:Rn项目apk,win10,android手机,as版本为4.2.2。======================================================================================================这是由chatG......
  • 工程监测多通道振弦模拟信号采集仪VTN常规操作
    工程监测多通道振弦模拟信号采集仪VTN常规操作 一、开关机1、开机VTN4XX有四个开机途径,手动开机、自动定时开机和上电开机、信号触发开机。上电开机:当“工作模式拨码......
  • L5-NOIP模拟11 测试题解
    经典老题排名-L5-NOIP模拟11-码创未来A.[CQOI2009]中位数洛谷P1627|码创未来题意给出\(1,2,\dots,n\)的一个排列,统计该排列有多少个长度为奇数的连续子串......