Win32/ C++ 简易对话框封装框架(多语言, 通知栏菜单, 拖拽文件处理)

Win32 简易对话框封装简易框架示例

1. 菜单操作: 多语言

2. 通知栏图标菜单

3. 其他操作: 接受拖拽文件等等 

CDialogFrame.h

#pragma once
#include "CWindow/CDialogBase.h"
#include "CNSFHeader.h"
#include "Win32Utils/CBytesUtils.h"
#include "Win32Utils/CIniHelper.h"

#define HELP_ABOUT_URL "https://gitee.com/flame_cyclone/nsf_information_editor"


#define CONFIG_INI_ROOT                                   _T("config")
#define CONFIG_INI_TOPMOST                                _T("settings_topmost")
#define CONFIG_INI_LANGUAGE                               _T("settings_language")

class CDialogFrame :
	public CDialogBase
{
public:
    LRESULT OnCommand(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);

protected:

    dlg_msg LRESULT OnInitDialog(WPARAM wParam, LPARAM lParam);
	dlg_msg LRESULT OnClose(WPARAM wParam, LPARAM lParam);
    dlg_msg LRESULT OnRButtonUp(WPARAM wParam, LPARAM lParam);
    dlg_msg LRESULT OnDropFiles(WPARAM wParam, LPARAM lParam);
    dlg_msg LRESULT OnWindowPosChinging(WPARAM wParam, LPARAM lParam);
    dlg_command LRESULT OnTrayIcon(WPARAM wParam, LPARAM lParam);
    dlg_command LRESULT OnFileOpen(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnFileSave(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnFileSaveAs(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnFileExit(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsTopmost(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnRadioStandard(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnHelpAbout(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_zh_CN(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_zh_SG(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_zh_HK(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_zh_TW(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_zh_MO(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_ja_JP(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_ko_KR(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);
    dlg_command LRESULT OnSettingsLang_en_US(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd);

    virtual BOOL PreTranslateMessage(LPMSG pMsg);

private:
    bool InputLimitLength(HWND hWnd, int nLength = -1);
    bool InputLimitDec(HWND hWnd, int nLength = -1, UINT nMin = 0, UINT nMax = UINT_MAX);
    bool InputLimitHex(HWND hWnd, int nLength = -1, UINT nMin = 0, UINT nMax = UINT_MAX);
    void LanguageChange(LANGID lang);
    void LoadInformationFromFile(const _tstring& strFile);
    void SaveInformationFromFile(const _tstring& strFile);
    void LoadInformationFromNSFHeader(const NSF_HEADER& header);
    bool IsNsfFormat(const NSF_HEADER& header);

    void ShowTrayIcon();
    void DeleteTrayIcon();
    VOID CreatePopMenu(int xPos, int yPos, bool isTop);
    bool ShowForeground(HWND hWnd);

private:
    HMENU                   m_hPopMenu = NULL;
    HMENU                   m_hMainMenu = NULL;
    HWND                    m_hHideWnd = NULL;

    LANGID                  m_langID;
    CIniHelper              m_cfg;
    std::vector<uint8_t>    m_nsfData;
    NSF_HEADER              m_nsfHeader = { 0 };
    _tstring                m_strPath;
    bool                    m_fBusy = false;

	DECLARE_DLG_MESSAGE_MAP()
};

CDialogFrame.cpp

#include "CDialogFrame.h"
#include <Windows.h>
#include <strsafe.h>
#include <imm.h>
#include <thread>
#include "resource.h"
#include "Win32Utils/CStrUtils.h"
#include "Win32Utils/CComFileDlg.h"
#include "Win32Utils/CPathUtils.h"
#include "Win32Utils/CMessageBoxCenter.h"
#include "Win32Utils/CVersionUtils.h"

#pragma comment(lib ,"imm32.lib")
#pragma comment(lib, "SetupAPI.lib")
#pragma comment(lib, "Bthprops.lib")

#define WM_TRAYICON                 (WM_USER + 10)

BEGIN_DLG_MESSAGE_MAP(CDialogFrame, CDialogBase)
    ON_DLG_MESSAGE(WM_INITDIALOG, &CDialogFrame::OnInitDialog)
    ON_DLG_MESSAGE(WM_CLOSE, &CDialogFrame::OnClose)
    ON_DLG_MESSAGE(WM_WINDOWPOSCHANGING, &CDialogFrame::OnWindowPosChinging)
    ON_DLG_MESSAGE(WM_RBUTTONUP, &CDialogFrame::OnRButtonUp)
    ON_DLG_MESSAGE(WM_TRAYICON, &CDialogFrame::OnTrayIcon)
    ON_DLG_MESSAGE(WM_DROPFILES, &CDialogFrame::OnDropFiles)
    ON_DLG_COMMAND(IDC_BUTTON_OPEN_FILE, &CDialogFrame::OnFileOpen)
    ON_DLG_COMMAND(ID_FILE_OPEN, &CDialogFrame::OnFileOpen)
    ON_DLG_COMMAND(ID_FILE_SAVE, &CDialogFrame::OnFileSave)
    ON_DLG_COMMAND(ID_FILE_SAVE_AS, &CDialogFrame::OnFileSaveAs)
    ON_DLG_COMMAND(ID_FILE_EXIT, &CDialogFrame::OnFileExit)
    ON_DLG_COMMAND(ID_SETTINGS_TOPMOST, &CDialogFrame::OnSettingsTopmost)
    ON_DLG_COMMAND(ID_HELP_ABOUT, &CDialogFrame::OnHelpAbout)
    ON_DLG_COMMAND(ID_LANGUAGE_ZH_CN, &CDialogFrame::OnSettingsLang_zh_CN)
    ON_DLG_COMMAND(ID_LANGUAGE_ZH_SG, &CDialogFrame::OnSettingsLang_zh_SG)
    ON_DLG_COMMAND(ID_LANGUAGE_ZH_HK, &CDialogFrame::OnSettingsLang_zh_HK)
    ON_DLG_COMMAND(ID_LANGUAGE_ZH_TW, &CDialogFrame::OnSettingsLang_zh_TW)
    ON_DLG_COMMAND(ID_LANGUAGE_ZH_MO, &CDialogFrame::OnSettingsLang_zh_MO)
    ON_DLG_COMMAND(ID_LANGUAGE_JA_JP, &CDialogFrame::OnSettingsLang_ja_JP)
    ON_DLG_COMMAND(ID_LANGUAGE_KO_KR, &CDialogFrame::OnSettingsLang_ko_KR)
    ON_DLG_COMMAND(ID_LANGUAGE_EN_US, &CDialogFrame::OnSettingsLang_en_US)
    ON_DLG_COMMAND_RANGE(IDC_RADIO_STANDARD_NTSC, IDC_RADIO_STANDARD_NTSC_PAL, &CDialogFrame::OnRadioStandard)
END_DLG_MESSAGE_MAP()

LRESULT CDialogFrame::OnInitDialog(WPARAM wParam, LPARAM lParam)
{
    m_hHideWnd = CreateWindow(
        _T("Static"), _T("Hide"), WS_CHILDWINDOW, 0, 0, 0, 0,
        m_hWnd, NULL, GetModuleHandle(NULL), NULL);
    if (m_hHideWnd)
    {
        ::SetParent(m_hHideWnd, NULL);
    }

    m_hMainMenu = ::GetMenu(m_hWnd);
    if (m_hMainMenu)
    {
        ShowTrayIcon();
    }

    CHANGEFILTERSTRUCT cfs = { 0 };
    cfs.cbSize = sizeof(cfs);

    //允许低权限进程拖动文件进来
    ChangeWindowMessageFilterEx(m_hWnd, WM_DROPFILES, MSGFLT_ALLOW, &cfs);
    ChangeWindowMessageFilterEx(m_hWnd, WM_COPYDATA, MSGFLT_ALLOW, &cfs);
    ChangeWindowMessageFilterEx(m_hWnd, WM_COPYDATA - 1, MSGFLT_ALLOW, &cfs);

    ::SetMenu(m_hWnd, m_hMainMenu);

    HICON hIconSmall = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_MAIN));
    HICON hIconBig = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_MAIN));
    if (hIconBig)
    {
        ::SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIconBig);
    }

    if (hIconSmall)
    {
        ::SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall);
    }

    // 禁用输入法
    ImmAssociateContext(GetItem(IDC_EDIT_TOTAL_SONGS), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_START_SONG), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_LOAD_ADDR), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_INIT_ADDR), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_PLAY_ADDR), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_NAME), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_ARTIST), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_COPYRIGHT), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_PLAY_SPEED_NTSC), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_PLAY_SPEED_PAL), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_0), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_1), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_2), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_3), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_4), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_5), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_6), NULL);
    ImmAssociateContext(GetItem(IDC_EDIT_BANK_7), NULL);
    
    NSF_HEADER header = { 0 };
    LoadInformationFromNSFHeader(header);

    if (m_cfg.GetInt(CONFIG_INI_ROOT, CONFIG_INI_TOPMOST, true))
    {
        PostCommand(ID_SETTINGS_TOPMOST);
    }

    _tstring strLanguage = m_cfg.GetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T(""));
    if (_T("zh_CN") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_ZH_CN);
    }
    else if (_T("zh_SG") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_ZH_SG);
    }
    else if (_T("zh_HK") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_ZH_HK);
    }
    else if (_T("zh_TW") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_ZH_TW);
    }
    else if (_T("zh_MO") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_ZH_MO);
    }
    else if (_T("ja_JP") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_JA_JP);
    }
    else if (_T("ko_KR") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_KO_KR);
    }
    else if (_T("en_US") == strLanguage)
    {
        PostCommand(ID_LANGUAGE_EN_US);
    }
    else
    {
        LANGID langID = GetThreadUILanguage();
        if (LANG_CHINESE == PRIMARYLANGID(langID))
        {
            if (SUBLANG_CHINESE_HONGKONG == SUBLANGID(langID))
            {
                PostCommand(ID_LANGUAGE_ZH_HK);
            }
            else if (SUBLANG_CHINESE_TRADITIONAL == SUBLANGID(langID))
            {
                PostCommand(ID_LANGUAGE_ZH_TW);
            }
            else if (SUBLANG_CHINESE_SINGAPORE == SUBLANGID(langID))
            {
                PostCommand(ID_LANGUAGE_ZH_SG);
            }
            else if (SUBLANG_CHINESE_MACAU == SUBLANGID(langID))
            {
                PostCommand(ID_LANGUAGE_ZH_MO);
            }
            else
            {
                PostCommand(ID_LANGUAGE_ZH_CN);
            }
        }
        else if(LANG_JAPANESE == PRIMARYLANGID(langID))
        {
            PostCommand(ID_LANGUAGE_JA_JP);
        }
        else if (LANG_KOREAN == PRIMARYLANGID(langID))
        {
            PostCommand(ID_LANGUAGE_KO_KR);
        }
        else
        {
            PostCommand(ID_LANGUAGE_EN_US);
        }
    }

    LoadAccel(IDR_ACCELERATOR_MAIN);

    return LRESULT(TRUE);
}

LRESULT CDialogFrame::OnRadioStandard(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    EnableItem(IDC_EDIT_PLAY_SPEED_NTSC, TRUE);
    EnableItem(IDC_EDIT_PLAY_SPEED_PAL, TRUE);
    if (wID == IDC_RADIO_STANDARD_NTSC) EnableItem(IDC_EDIT_PLAY_SPEED_PAL, FALSE);
    if (wID == IDC_RADIO_STANDARD_PAL) EnableItem(IDC_EDIT_PLAY_SPEED_NTSC, FALSE);
    return LRESULT(TRUE);
}

LRESULT CDialogFrame::OnWindowPosChinging(WPARAM wParam, LPARAM lParam)
{
    LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)lParam;
    lpWindowPos->flags |= SWP_NOSIZE;
    return LRESULT(TRUE);
}

LRESULT CDialogFrame::OnClose(WPARAM wParam, LPARAM lParam)
{
    return (LRESULT)FALSE;
}

dlg_msg LRESULT CDialogFrame::OnRButtonUp(WPARAM wParam, LPARAM lParam)
{
    int xPos = GET_X_LPARAM(lParam);
    int yPos = GET_Y_LPARAM(lParam);
    POINT pt = { xPos, yPos };
    ClientToScreen(m_hWnd, &pt);
    CreatePopMenu(pt.x, pt.y, false);
    return LRESULT(TRUE);
}

LRESULT CDialogFrame::OnCommand(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    LONG_PTR style = GetWindowLongPtr(GetItem(wID), GWL_STYLE);

    if ((BS_RADIOBUTTON == (BS_RADIOBUTTON & style)) || (BS_AUTORADIOBUTTON == (BS_AUTORADIOBUTTON & style)))
    {
        if (wNotify == 0)
        {
            CheckRadioButton(wStart, wEnd, wID);
        }
    }

    return (LRESULT)FALSE;
}

LRESULT CDialogFrame::OnDropFiles(WPARAM wParam, LPARAM lParam)
{
    HDROP hDrop = (HDROP)wParam;
    TCHAR szFile[MAX_PATH] = { 0 };
    UINT nCount = DragQueryFile(hDrop, (UINT)(-1), szFile, _countof(szFile));

    for (UINT i = 0; i < nCount; i++)
    {
        ::DragQueryFile(hDrop, i, szFile, _countof(szFile));
        if (_T("nsf") == CPathUtils::GetFileExt(szFile))
        {
            LoadInformationFromFile(szFile);
            break;
        }
    }

    DragFinish(hDrop);

    return TRUE;
}

LRESULT CDialogFrame::OnFileOpen(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    if (m_fBusy)
    {
        return (LRESULT)TRUE;
    }

    m_fBusy = true;
    std::thread([this, wID]() {

        SetThreadUILanguage(m_langID);
        UINT uIndex = 0;
        COMDLG_FILTERSPEC filters[] = { { _T("nsf"), _T("*.nsf") } };
        _tstring strPath = m_strPath;
        if (CComFileDlg::GetOpenPath(m_hWnd, strPath, uIndex, filters, _countof(filters)))
        {
            LoadInformationFromFile(strPath);
        }
        m_fBusy = false;
        }
    ).detach();

    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnFileSave(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    if (!m_strPath.empty())
    {
        SaveInformationFromFile(m_strPath);
    }
    else
    {
        PostCommand(ID_FILE_SAVE_AS);
    }
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnFileSaveAs(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    if (m_fBusy)
    {
        return (LRESULT)TRUE;
    }

    m_fBusy = true;
    std::thread([this, wID]() {

        SetThreadUILanguage(m_langID);
        UINT uIndex = 0;
        COMDLG_FILTERSPEC filters[] = { { _T("nsf"), _T("*.nsf") } };
        if (CComFileDlg::GetSavePath(m_hWnd, m_strPath, uIndex, filters, _countof(filters)))
        {
            if (0 !=  CStrUtils::CompareNoCase(CPathUtils::GetFileExt(m_strPath, false), _T("nsf")))
            {
                m_strPath += _T(".nsf");
            }

            SaveInformationFromFile(m_strPath);
        }
        m_fBusy = false;
        }
    ).detach();

    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnFileExit(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    PostMessage(WM_CLOSE);
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsTopmost(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    bool fChecked = IsMenuItemChecked(hMenu, wID, false);
    fChecked = !fChecked;
    CheckMenuItem(hMenu, wID, fChecked, false);
    ::SetWindowPos(m_hWnd, fChecked ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    m_cfg.SetInt(CONFIG_INI_ROOT, CONFIG_INI_TOPMOST, fChecked);
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnHelpAbout(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    ::ShellExecute(NULL, _T("open"), _T(HELP_ABOUT_URL), NULL, NULL, SW_SHOW);
    return LRESULT(TRUE);
}

LRESULT CDialogFrame::OnSettingsLang_zh_CN(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("zh_CN"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_zh_SG(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("zh_SG"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_zh_HK(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("zh_HK"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_zh_TW(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("zh_TW"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_zh_MO(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_MACAU));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("zh_MO"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_ja_JP(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("ja_JP"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_ko_KR(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_KOREAN, SUBLANG_JAPANESE_JAPAN));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("ko_KR"));
    return (LRESULT)TRUE;
}

LRESULT CDialogFrame::OnSettingsLang_en_US(WORD wNotify, WORD wID, HWND hWnd, WORD wStart, WORD wEnd)
{
    HMENU hMenu = GetMenu(m_hWnd);
    CheckRadioMenuItem(hMenu, wID, true);
    LanguageChange(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
    m_cfg.SetString(CONFIG_INI_ROOT, CONFIG_INI_LANGUAGE, _T("en_US"));
    return (LRESULT)TRUE;
}

void CDialogFrame::LanguageChange(LANGID lang)
{
    m_langID = lang;
    SetThreadUILanguage(lang);

    //修改菜单文本
    {
        HMENU hMenu = GetMenu(m_hWnd);
        ModifyMenuText(hMenu, 0, IDS_STRING_FILE, TRUE);
        ModifyMenuText(hMenu, ID_FILE_OPEN, IDS_STRING_FILE_OPEN, FALSE);
        ModifyMenuText(hMenu, ID_FILE_SAVE, IDS_STRING_FILE_SAVE, FALSE);
        ModifyMenuText(hMenu, ID_FILE_SAVE_AS, IDS_STRING_FILE_SAVE_AS, FALSE);
        ModifyMenuText(hMenu, ID_FILE_EXIT, IDS_STRING_FILE_EXIT, FALSE);

        ModifyMenuText(hMenu, 1, IDS_STRING_SETTINGS, TRUE);
        ModifyMenuText(hMenu, ID_SETTINGS_TOPMOST, IDS_STRING_SETTINGS_TOPMOST, FALSE);
        ModifyMenuText(::GetSubMenu(hMenu, 1), 1, IDS_STRING_SETTINGS_LANGUAGE, TRUE);

        ModifyMenuText(hMenu, 2, IDS_STRING_HELP, TRUE);
        ModifyMenuText(hMenu, ID_HELP_ABOUT, IDS_STRING_HELP_ABOUT, FALSE);
    }

    //界面文本
    {
        SetItemString(IDC_STATIC_FILE_PATH, LoadString(IDS_STRING_PATH));
        SetItemString(IDC_BUTTON_OPEN_FILE, LoadString(IDS_STRING_OPEN));
        SetItemString(IDC_STATIC_TOTAL_SONGS, LoadString(IDS_STRING_TOTAL_SONGS));
        SetItemString(IDC_STATIC_START_SONG, LoadString(IDS_STRING_START_SONG));
        SetItemString(IDC_STATIC_LOAD_ADDR, LoadString(IDS_STRING_LOAD_ADDR));
        SetItemString(IDC_STATIC_INIT_ADDR, LoadString(IDS_STRING_INIT_ADDR));
        SetItemString(IDC_STATIC_PLAY_ADDR, LoadString(IDS_STRING_PLAY_ADDR));
        SetItemString(IDC_STATIC_NAME, LoadString(IDS_STRING_NAME));
        SetItemString(IDC_STATIC_ARTIST, LoadString(IDS_STRING_ARTIST));
        SetItemString(IDC_STATIC_COPYRIGHT, LoadString(IDS_STRING_COPYRIGHT));
        SetItemString(IDC_STATIC_STANDARD, LoadString(IDS_STRING_STANDARD));
        SetItemString(IDC_STATIC_PLAY_SPEED, LoadString(IDS_STRING_PLAY_SPEED));
        SetItemString(IDC_STATIC_BANKSWITCH, LoadString(IDS_STRING_BANKSWITCH));
        SetItemString(IDC_STATIC_EXTRA_SOUND, LoadString(IDS_STRING_EXTRA_SOUND));
    }

    // 标题
    {
        _tstring strCaption = LoadString(IDS_STRING_CAPTION);
        CVersionUtils::VERSION_INFO version = CVersionUtils::GetFileVersion(CPathUtils::GetCurrentModulePath());
        if (!version.strFileVersion.empty())
        {
            strCaption += _T(" ");
            strCaption += version.strFileVersion;
        }

        if (!version.strCompanyName.empty())
        {
            strCaption += _T(" ");
            strCaption += _T("(");
            strCaption += version.strCompanyName;
            strCaption += _T(")");
        }

        ::SetWindowText(m_hWnd, strCaption.c_str());
    }

    ::DrawMenuBar(m_hWnd);
}

LRESULT CDialogFrame::OnTrayIcon(WPARAM wParam, LPARAM lParam)
{
    if (WM_LBUTTONDBLCLK == lParam)
    {
        ShowForeground(m_hWnd);
    }

    if (NULL != m_hHideWnd)
    {
        ::SetForegroundWindow(m_hHideWnd);
    }

    if (WM_RBUTTONUP == lParam)
    {
        HWND hForegroundWindow = GetForegroundWindow();
        if (hForegroundWindow == m_hHideWnd || hForegroundWindow == m_hWnd)
        {
            POINT pt = { 0 };
            ::GetCursorPos(&pt);
            CreatePopMenu(pt.x, pt.y, false);
        }
    }

    return FALSE;
}

bool CDialogFrame::ShowForeground(HWND hWnd)
{
    HWND hForeWnd = ::GetForegroundWindow();
    DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd, NULL);
    DWORD dwCurID = ::GetCurrentThreadId();
    ::AttachThreadInput(dwCurID, dwForeID, TRUE);
    BOOL isSuc = ::SetForegroundWindow(hWnd);
    ::AttachThreadInput(dwCurID, dwForeID, FALSE);

    if (isSuc)
    {
        //return true;
    }

    if (!::IsWindowVisible(hWnd))
    {
        ::ShowWindow(hWnd, SW_SHOW);
    }

    if (IsIconic(hWnd))
    {
        ::ShowWindow(hWnd, SW_SHOWNORMAL);
    }

    return ::SetForegroundWindow(hWnd);
}

void CDialogFrame::ShowTrayIcon()
{
    NOTIFYICONDATA nid = { 0 };
    nid.cbSize = sizeof(NOTIFYICONDATA);
    nid.hWnd = m_hWnd;
    nid.uID = 0;
    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
    nid.uCallbackMessage = WM_TRAYICON;
    nid.hIcon = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_MAIN));
    StringCchCopy(nid.szTip, _countof(nid.szTip), _T("Demo"));
    Shell_NotifyIcon(NIM_ADD, &nid);
}

void CDialogFrame::DeleteTrayIcon()
{
    NOTIFYICONDATA nid = { 0 };
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd;
    nid.uID = 0;
    nid.uFlags = 0;
    Shell_NotifyIcon(NIM_DELETE, &nid);
}

VOID CDialogFrame::CreatePopMenu(int xPos, int yPos, bool isTop)
{
    MENUITEMINFO mii = { 0 };
    TCHAR szBuf[MAX_PATH] = { 0 };

    mii.cbSize = sizeof(mii);
    mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
    mii.fType = MFT_STRING | MFT_OWNERDRAW;
    mii.dwTypeData = szBuf;

    if (!m_hWnd)
    {
        return;
    }

    {
        HMENU hMenu = m_hMainMenu;
        //ModifyMenuText(hMenu, ID_FILE_EXIT, IDS_FILE_EXIT, FALSE);
        //ModifyMenuText(hMenu, ID_SETTINGS_SHOW, IDS_SETTINGS_SHOW, FALSE);
        //ModifyMenuText(hMenu, ID_SETTINGS_HIDE, IDS_SETTINGS_HIDE, FALSE);
    }

    if (NULL == m_hPopMenu)
    {
        m_hPopMenu = CreatePopupMenu();
        int nCount = ::GetMenuItemCount(m_hMainMenu);
        for (int i = 0; i < nCount; i++)
        {
            mii.cch = _countof(szBuf);
            ::GetMenuItemInfo(m_hMainMenu, i, TRUE, &mii);
            ::InsertMenuItem(m_hPopMenu, i, TRUE, &mii);
        }
    }
    else
    {
        int nCount = ::GetMenuItemCount(m_hMainMenu);
        for (int i = 0; i < nCount; i++)
        {
            mii.cch = _countof(szBuf);
            ::GetMenuItemInfo(m_hMainMenu, i, TRUE, &mii);
            ::SetMenuItemInfo(m_hPopMenu, i, TRUE, &mii);
        }
    }

    TrackPopupMenuEx(m_hPopMenu, TPM_LEFTALIGN | (isTop ? TPM_BOTTOMALIGN : TPM_TOPALIGN),
        xPos, yPos, m_hWnd, NULL);
}

void CDialogFrame::LoadInformationFromFile(const _tstring& strFile)
{
    m_strPath = strFile;
    if (CBytesUtils::BytesFromFile(m_nsfData, m_strPath))
    {
        if (m_nsfData.size() >= sizeof(m_nsfHeader))
        {
            NSF_HEADER nsfHeader = { 0 };
            memcpy(&nsfHeader, m_nsfData.data(), sizeof(nsfHeader));

            if (IsNsfFormat(nsfHeader))
            {
                LoadInformationFromNSFHeader(nsfHeader);
                m_strPath = strFile;
                m_nsfHeader = nsfHeader;
                SetItemString(IDC_EDIT_FILE_PATH, m_strPath);
            }
            else
            {
                CMessageBoxCenter       m_boxCenter;
                MessageBox(m_hWnd,
                    LoadString(IDS_STRING_FORMAT_INCORRENT).c_str(),
                    LoadString(IDS_STRING_ERROR).c_str(),
                    MB_OK | MB_ICONERROR);
                m_strPath.clear();
                SetItemString(IDC_EDIT_FILE_PATH, m_strPath);
            }
        }
    }
}

void CDialogFrame::LoadInformationFromNSFHeader(const NSF_HEADER& header)
{
    SetItemInt(IDC_EDIT_TOTAL_SONGS, header.total_songs);
    SetItemInt(IDC_EDIT_START_SONG, header.start_song);

    SetItemString(IDC_EDIT_LOAD_ADDR, CStrUtils::Format(_T("%04X"), header.load_address));
    SetItemString(IDC_EDIT_INIT_ADDR, CStrUtils::Format(_T("%04X"), header.init_address));
    SetItemString(IDC_EDIT_PLAY_ADDR, CStrUtils::Format(_T("%04X"), header.play_address));

    SetItemString(IDC_EDIT_NAME, CStrUtils::U8StrToTStr(header.name));
    SetItemString(IDC_EDIT_ARTIST, CStrUtils::U8StrToTStr(header.artist));
    SetItemString(IDC_EDIT_COPYRIGHT, CStrUtils::U8StrToTStr(header.copyright));

    SetItemString(IDC_EDIT_PLAY_SPEED_NTSC, CStrUtils::Format(_T("%d"), header.play_speed_ntsc));
    SetItemString(IDC_EDIT_PLAY_SPEED_PAL, CStrUtils::Format(_T("%d"), header.play_speed_pal));

    for (int i = 0; i < 8; i++)
    {
        SetItemString(IDC_EDIT_BANK_0 + i, CStrUtils::Format(_T("%02X"), header.bankswitch[i]));
    }

    switch (header.standard)
    {
    case 0:
        CheckRadioButton(IDC_RADIO_STANDARD_NTSC, IDC_RADIO_STANDARD_NTSC_PAL, IDC_RADIO_STANDARD_NTSC);
        EnableItem(IDC_EDIT_PLAY_SPEED_NTSC, TRUE);
        EnableItem(IDC_EDIT_PLAY_SPEED_PAL, FALSE);
        break;
    case 1:
        CheckRadioButton(IDC_RADIO_STANDARD_NTSC, IDC_RADIO_STANDARD_NTSC_PAL, IDC_RADIO_STANDARD_PAL);
        EnableItem(IDC_EDIT_PLAY_SPEED_NTSC, FALSE);
        EnableItem(IDC_EDIT_PLAY_SPEED_PAL, TRUE);
        break;
    case 2:
        CheckRadioButton(IDC_RADIO_STANDARD_NTSC, IDC_RADIO_STANDARD_NTSC_PAL, IDC_RADIO_STANDARD_NTSC_PAL);
        EnableItem(IDC_EDIT_PLAY_SPEED_NTSC, TRUE);
        EnableItem(IDC_EDIT_PLAY_SPEED_PAL, TRUE);
        break;
    }

    for (int i = 0; i < 7; i++)
    {
        CheckButton(IDC_CHECK_AUDIO_VRC6 + i, header.extra_sound & (0x01 << i));
    }
}

bool CDialogFrame::IsNsfFormat(const NSF_HEADER& header)
{
    if (0x4D53454E == *(uint32_t*)&header.format_file &&
        0x1A == header.format_file[4]
        )
    {
        return true;
    }

    return false;
}

void CDialogFrame::SaveInformationFromFile(const _tstring& strPath)
{
    std::vector<uint8_t> vData = m_nsfData;
    NSF_HEADER  nsfHeader = { 0 };

    if (vData.size() < sizeof(nsfHeader))
    {
        vData.resize(sizeof(nsfHeader));
    }

    nsfHeader.format_file[0] = 0x4E;
    nsfHeader.format_file[1] = 0x45;
    nsfHeader.format_file[2] = 0x53;
    nsfHeader.format_file[3] = 0x4D;
    nsfHeader.format_file[4] = 0x1A;

    nsfHeader.total_songs = GetItemInt(IDC_EDIT_TOTAL_SONGS);
    nsfHeader.start_song = GetItemInt(IDC_EDIT_START_SONG);
    nsfHeader.load_address = CStrUtils::StrToUInt(GetItemString(IDC_EDIT_LOAD_ADDR), 16);
    nsfHeader.init_address = CStrUtils::StrToUInt(GetItemString(IDC_EDIT_INIT_ADDR), 16);
    nsfHeader.play_address = CStrUtils::StrToUInt(GetItemString(IDC_EDIT_PLAY_ADDR), 16);

    std::string strName = CStrUtils::TStrToU8Str(GetItemString(IDC_EDIT_NAME));
    std::string strArtist = CStrUtils::TStrToU8Str(GetItemString(IDC_EDIT_ARTIST));
    std::string strCopyRight = CStrUtils::TStrToU8Str(GetItemString(IDC_EDIT_COPYRIGHT));
    if (strName.size() > 31) strName.resize(31);
    if (strArtist.size() > 31) strArtist.resize(31);
    if (strCopyRight.size() > 31) strCopyRight.resize(31);
    memcpy(nsfHeader.name, strName.c_str(), strName.size());
    memcpy(nsfHeader.artist, strArtist.c_str(), strArtist.size());
    memcpy(nsfHeader.copyright, strCopyRight.c_str(), strCopyRight.size());

    nsfHeader.play_speed_ntsc = GetItemInt(IDC_EDIT_PLAY_SPEED_NTSC);
    nsfHeader.play_speed_pal = GetItemInt(IDC_EDIT_PLAY_SPEED_PAL);

    for (int i = 0; i < 8; i++)
    {
        nsfHeader.bankswitch[i] = CStrUtils::StrToUInt(GetItemString(IDC_EDIT_BANK_0 + i), 16);
    }

    if (IsButtonChecked(IDC_RADIO_STANDARD_NTSC)) nsfHeader.standard = 0x00;
    if (IsButtonChecked(IDC_RADIO_STANDARD_PAL)) nsfHeader.standard = 0x01;
    if (IsButtonChecked(IDC_RADIO_STANDARD_NTSC_PAL)) nsfHeader.standard = 0x02;

    for (int i = 0; i < 7; i++)
    {
        if (IsButtonChecked(IDC_CHECK_AUDIO_VRC6 + i))
        {
            nsfHeader.extra_sound |= (1 << i);
        }
    }

    memcpy(vData.data(), &nsfHeader, sizeof(nsfHeader));

    CBytesUtils::BytesToFile(strPath, vData);

    SetItemString(IDC_EDIT_FILE_PATH, m_strPath);
}

BOOL CDialogFrame::PreTranslateMessage(LPMSG pMsg)
{
    if (WM_KEYDOWN == pMsg->message)
    {
        UINT vkCode = (UINT)pMsg->wParam;
        SHORT fCtrl = GetAsyncKeyState(VK_CONTROL) & 0x8000;

        // 删除忽略
        if (VK_BACK == vkCode || VK_DELETE == vkCode)
        {
            return FALSE;
        }

        // 组合键忽略
        if (fCtrl)
        {
            if (vkCode == 'C' || vkCode == 'V' || vkCode == 'X' || vkCode == 'Z' || vkCode == 'A')
            {
                return FALSE;
            }
        }

        // 方向位置忽略
        if (vkCode >= VK_END && vkCode <= VK_DOWN)
        {
            return FALSE;
        }

        if (GetItem(IDC_EDIT_NAME) == pMsg->hwnd)
        {
            return InputLimitLength(pMsg->hwnd, 31);
        }
        if (GetItem(IDC_EDIT_ARTIST) == pMsg->hwnd)
        {
            return InputLimitLength(pMsg->hwnd, 31);
        }
        if (GetItem(IDC_EDIT_COPYRIGHT) == pMsg->hwnd)
        {
            return InputLimitLength(pMsg->hwnd, 31);
        }
    }

    return FALSE;
}

bool CDialogFrame::InputLimitLength(HWND hWnd, int nLength/* = -1*/)
{
    int iStart = 0;
    int iEnd = 0;
    int iSelect = 0;
    ::SendMessage(hWnd, EM_GETSEL, (WPARAM)&iStart, (LPARAM)&iEnd);

    iSelect = iEnd - iStart;

    int nCurLength = GetItemStringLength(hWnd);
    if (nCurLength >= nLength)
    {
        if (iSelect > 0)
        {
            return false;
        }

        return true;
    }

    _tstring strText = GetItemString(hWnd);

    return false;
}

bool CDialogFrame::InputLimitDec(HWND hWnd, int nLength/* = -1*/, UINT nMin/* = 0*/, UINT nMax/* = UINT_MAX*/)
{
    return false;
}

bool CDialogFrame::InputLimitHex(HWND hWnd, int nLength/* = -1*/, UINT nMin/* = 0*/, UINT nMax/* = UINT_MAX*/)
{
    return false;
}

main.cpp

#include "CDialogFrame.h"
#include "resource.h"

int APIENTRY WinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ int nShowCmd)
{
    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nShowCmd);

    CDialogFrame dlg;
    dlg.DoModalEx(IDD_DIALOG_MAIN, nullptr);

    return 0;
}

 完整项目仓库

https://gitee.com/flame_cyclone/nsf_information_editor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/977779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Linux 上安装和配置 Zsh

文章目录 如何在 Linux 上安装和配置 Zsh1. 安装 Zsh1.1 在 Ubuntu/Debian 上安装1.2 在 CentOS/RHEL/Fedora 上安装1.3 在 Arch Linux 上安装1.4 验证 Zsh 安装 2. 设置 Zsh 为默认 Shell2.1 验证默认 shell 3. 配置 Zsh3.1 使用 Oh My Zsh3.1.1 安装 Oh My Zsh3.1.2 启用插件…

Ubuntu搭建esp32环境 配置打开AT指令集 websocket功能

1&#xff0c;搭建前提 环境搭建参考乐鑫官网给的本地编译 ESP-AT 工程方法 因为公司电脑和网络的特殊性&#xff0c;不能正确解析域名&#xff08;仅在浏览器上可以访问&#xff09; &#xff0c;所以这边访问的时候改成了ssh 未了避免使用外网困难的问题&#xff0c;这里用…

网络安全第三次练习

一、实验拓扑 二、实验要求 配置真实DNS服务信息&#xff0c;创建虚拟服务&#xff0c;配置DNS透明代理功能 三、需求分析 1.创建用户并配置认证策略 2.安全策略划分接口 3.ip与策略配置 四、实验步骤 1.划分安全策略接口 2.创建用户并进行策略认证 3.配置安全策略 4.NAT配…

Web自动化之Selenium下Chrome与Edge的Webdriver常用Options参数

目录 引言 说明 Add_argument() 添加方式 常用参数 Add_experimental_option() 添加方式 常用方法 任务结束后仍然保持浏览器打开 禁用“Chrome 正受到自动测试软件的控制”提示 设置下载路径 禁用弹窗拦截 禁用图片加载 禁用 JavaScript 注意 引言 …

【无标题】网络安全公钥密码体制

第一节 网络安全 概述 一、基本概念 网络安全通信所需要的基本属性“ 机密性&#xff1b;消息完整性&#xff1b;可访问性与可用性&#xff1b;身份认证。 二、网络安全威胁 窃听&#xff1b;插入&#xff1b;假冒&#xff1b;劫持&#xff1b;拒绝服务Dos和分布式拒绝服务…

2024年国赛高教杯数学建模D题反潜航空深弹命中概率问题解题全过程文档及程序

2024年国赛高教杯数学建模 D题 反潜航空深弹命中概率问题 原题再现 应用深水炸弹&#xff08;简称深弹&#xff09;反潜&#xff0c;曾是二战时期反潜的重要手段&#xff0c;而随着现代军事技术的发展&#xff0c;鱼雷已成为现代反潜作战的主要武器。但是&#xff0c;在海峡或…

在vscode中编译运行c语言文件,配置并运行OpenMP多线程并行程序设计

1.下载安装vscode Visual Studio Code - Code Editing. Redefined 2.安装vscode扩展 打开vscode,按ctrl+shift+x,打开扩展,搜索c/c++,下载相应的扩展 3.下载MinGW-w64 MinGW-w64 提供了 GNU 编译器集合,可以编译c/c++文件 这里下载见我的资源,可直接下载 把压缩包解压…

PyCharm Professional 2025 安装配置全流程指南(Windows平台)

一、软件定位与核心功能 PyCharm 2025 是 JetBrains 推出的智能 Python IDE&#xff0c;新增深度学习框架自动补全、实时性能热力图等功能1。相较于社区版&#xff0c;专业版支持&#xff1a; Web开发&#xff08;Django/Flask&#xff09;数据库工具&#xff08;PostgreSQL/…

从两地三中心到多地多中心,OceanBase如何实现金融级高可用

“两地三中心”已成为金融领域基准的容灾部署模式。本文将简要阐述金融行业容灾架构中“两地三中心”的具体要求和部署&#xff0c;并进一步探讨OceanBase在实现“两地三中心”标准后&#xff0c;再至“多地多中心”部署中所展现的独特优势与特点。 商业银行的容灾要求 《商业…

九、数据治理架构流程

一、总体结构 《数据治理架构流程图》&#xff08;Data Governance Architecture Flowchart&#xff09; 水平结构&#xff1a;流程图采用水平组织&#xff0c;显示从数据源到数据应用的进程。 垂直结构&#xff1a;每个水平部分进一步划分为垂直列&#xff0c;代表数据治理的…

6.将cr打包成网络服务|使用postman进行测试|编写oj_server的服务路由功能(C++)

将cr打包成网络服务 compile_server.cc #include "compile_run.hpp" #include "../comm/httplib.h"using namespace ns_compile_and_run; using namespace httplib;//编译服务随时可能被多个人请求&#xff0c;必须保证传递上来的code&#xff0c;形成源…

js前端数据加密 CryptoJS库加密 黑盒情况下寻找web的加密算法 代码混淆

前言 前端的数据加密是对用户的输入的一个常见的加密方法 还有的就是防止我们的sql注入 如 idMQ 这个其实解密出来就是 id 1 所以注入的思路就是 把 1和payload 一起加密然后 再进行注入 客户端的加密 > 数据加密传输 > 服务端解密 > 服务端的处理 传输的…

window平台上qtcreator上使用opencv报错

平台&#xff1a;win11 随便在网上下载一个别人编译好的opencv,发现运行报错 发现此次下载的opencv&#xff0c;别人在编译时选用的mingw版本应该和我电脑目前安装的mingw的版本不太一致 右键桌面的qtcreator图标&#xff0c;进入Tools目录&#xff0c;可以看到mingw的版本是…

Android之APP更新(通过接口更新)

文章目录 前言一、效果图二、实现步骤1.AndroidManifest权限申请2.activity实现3.有版本更新弹框UpdateappUtilDialog4.下载弹框DownloadAppUtils5.弹框背景图 总结 前言 对于做Android的朋友来说&#xff0c;APP更新功能再常见不过了&#xff0c;因为平台更新审核时间较长&am…

数字信任的底层逻辑:密码学核心技术与现实应用

安全和密码学 --The Missing Semester of Your CS Education 目录 熵与密码强度密码散列函数密钥体系 3.1 对称加密 3.2 非对称加密信任模型对比典型应用案例安全实践建议扩展练习杂项 密码学是构建数字信任的基石。 本文浅析密码学在现实工具中的应用&#xff0c;涵盖 1&…

达梦有没有类似oerr的功能

在oracle 23ai的sqlplus中&#xff0c;直接看异常信息说明&#xff1a; 达梦没有此功能&#xff0c;但是可以造一个 cd /home/dmdba cat >err.sql<<eof set echo off set ver off set timing off set lineshow off set feedback off select * from V\$ERR_INFO wher…

linux--多进程开发(5)--进程

进程间通讯概念 每两个进程之间都是独立的资源分配单元&#xff0c;不同进程之间不能直接访问另一个进程的资源。 但不同的进程需要进行信息的交互和状态的传递等&#xff0c;因此需要进程间通信&#xff08;IPC,inter processes cimmunication) 进程通信的目的&#xff1a; …

(二)趣学设计模式 之 工厂方法模式!

目录 一、 啥是工厂方法模式&#xff1f;二、 为什么要用工厂方法模式&#xff1f;三、 工厂方法模式怎么实现&#xff1f;四、 工厂方法模式的应用场景五、 工厂方法模式的优点和缺点六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博…

【c语言】字符函数和字符串函数(1)

一、字符分类函数 c语言中有部分函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符&#xff0c;这些函 数的使用要包含一个头文件ctype.h中。 其具体如下图所示&#xff1a; 这些函数的使用方式都类似&#xff0c;下面我们通过一个函数来看其…

网络安全 机器学习算法 计算机网络安全机制

&#xff08;一&#xff09;网络操作系统 安全 网络操作系统安全是整个网络系统安全的基础。操作系统安全机制主要包括访问控制和隔离控制。 访问控制系统一般包括主体、客体和安全访问政策 访问控制类型&#xff1a; 自主访问控制强制访问控制 访问控制措施&#xff1a; 入…