在網路上找到的資料或 AI 生成的範例,要真正能夠讓 wxMediaCtrl 動起來的方法都不是很完整,此文沒有高深的技巧,只是在初始建構上做補充。
要讓 wxMediaCtrl 能夠播放有兩點被 AI 忽略,建立時要指定後台播放器;以及要確定 Load 完成,即要捕捉 wxEVT_MEDIA_LOADED 這個事件。
在網路上找到的資料或 AI 生成的範例,要真正能夠讓 wxMediaCtrl 動起來的方法都不是很完整,此文沒有高深的技巧,只是在初始建構上做補充。
要讓 wxMediaCtrl 能夠播放有兩點被 AI 忽略,建立時要指定後台播放器;以及要確定 Load 完成,即要捕捉 wxEVT_MEDIA_LOADED 這個事件。
這是指在一次執行中把要替換的多筆字串一次完成,哪組先找到先替換,替換過的不能再被替換。有別於多次執行替換的處理。
關於拿掉 if (!f) return Src; 的原因在,只有 Replacements 為空時才會有作用可提早離開,並不會影響功能的正確性,絕大多數 Replacements 並不會是空的,沒必要多此一舉。
因 ChatGPT 同樣的問題每次的回答都不一樣,這次的作法覺得不錯,所以在這留一份。
對於詠唱詞我個人覺得,那是給 AI 看的不是給人看,意思是人是不是看得懂或是否覺得優美不重要,但若能兩者兼具那也很好,當作是詠唱詞與註解的結合
這是用 CodeBlocks 製作的專案,並須備好 C++ 編譯器和 wxWidgets,主要在介紹幾個 wxWidgets 強大的功能。程式雖然在 Windows 系統環境下寫的,但因 wxWidgets 是跨平台的程式庫,因此在其他系統環境下也應該可行。
程式的主要目的在達成程式與關聯檔案(Association File)的聯結,只要對關聯資料檔案點兩下,就可以叫出程式來虙理。
這次的目標在安裝 CxxlMan2 程式庫和多國語言插件,以及用一個簡單的例子做範例。在 CxxlMan2 的部份先下載以下檔案,並解壓到一個資料夾中,我是放在 ~/MySrc
$ sudo apt install gcc
$ sudo apt install c++
$ sudo apt-get install uuid-dev
為了能修訂 CxxlMan2 程式庫在 Linux 適用性,所以在 VMware 16.2.4 裝了一套 ubuntu-22.04.1-desktop-amd64 來用,但卻不能在 Host 與 Guest 之間複製檔案,上網找了一堆奇形怪招也沒用,浪費不少精神和時間。
後來無意間發現可以把一個 .txt 檔複製進去,才發現原來會阻擋副檔名為 .zip 的複製動作,還真是鳥屎^@#!&
一直都停留在使用 C++17 的標準,其中一個重要原因是 C++20 對 UTF-8 有了一個明確的型別定義,一些舊有的程式都過不了 C++20 這關,所以就一直攔著。
不過後來發現可以用強制型別指示轉換(type&)這招來破解,這招用在其他地方會很危險,因編譯器會無條件通過轉換,不會給你任何警告訊息。
C++20 對於 UTF-8 提供兩個新東西,一個 char8_t 型別,另一個是 std::u8string 類別,也只有這樣而已。最重要的 STL 完全只能用 char 和 std::string。
轉貼自 自然常數e為什麼這麼重要? - 知乎 (zhihu.com)
為免日後失連,所以在這裡備份一份,並轉為繁體中文。
由於原作是用一般打宇作敍述,沒法表現出數學式,所以這裡用 LaTex 幫忙修訂,但不碓定是否完全正確,所以有錯誤的地方還請不吝指正。
在 C++ 程式編譯之字串 一文中提到在 Console 顯示 wchar_t 字串的方法,但在 Windows 11 + MinGw 8.1.0 已經行不通了。不過現在比較流行用 UTF-8,若有在 Windows 的 Console 顯示 UTF-8 的須求,以下的方法很容易就能逹成
#include <iostream>
#include <Windows.h>
using namespace std;
int main(int, char**)
{
// Set console code page to UTF-8 so console known how to interpret string data
SetConsoleOutputCP(CP_UTF8);
// Enable buffering to prevent VS from chopping up UTF-8 byte sequences
setvbuf(stdout, nullptr, _IOFBF, 1000);
const char *str = u8"你好 こんにちは 안녕하십니까";
cout << "str = " << str << endl;
return 0;
}
這個小程式方便產生不同機率分佈的亂數,建構函數接受 vector<double> 含陣列各位置的機率分佈權值,實際運作時會傳回命中的陣列的索引
#include <chrono>
#include <random>
#include <iostream>
#include <vector>
using namespace std;
// 多機率分佈
class Multi_probability_distribution
{
size_t Max;
vector<double> m_Probability_accumulation;
public:
// Constructor
Multi_probability_distribution(const vector<double> &Probability_distribution)
:Max(Probability_distribution.size()-1),
m_Probability_accumulation(Probability_distribution.size())
{
m_Probability_accumulation[0] = Probability_distribution[0];
for (size_t i = 1; i <= Max; ++i)
m_Probability_accumulation[i] = m_Probability_accumulation[i - 1] +
Probability_distribution[i];
double Max_v = m_Probability_accumulation[Max];
for (double& v : m_Probability_accumulation)
v /= Max_v;
}
size_t operator()()
{
static minstd_rand0 Generator((unsigned)
chrono::system_clock::now().time_since_epoch().count());
static uniform_real_distribution<double> Distribution(0.0, 1.0);
double number = Distribution(Generator);
size_t Start = 0, End = Max;
// 二分搜尋加快速度
while (Start != End)
{
size_t Sel = (Start + End)/2;
if (number < m_Probability_accumulation[Sel])
End = Sel;
else
Start = Sel + 1;
}
return Start;
}
};
int main()
{
vector<double> pd{1,3,5}; // 期望陣列各位置的機率分佈權值
vector<size_t> Score(pd.size(),0); // 累記實際亂數產生所處位置
Multi_probability_distribution MPD(pd);
for (int i = 0; i < 100; ++i)
++Score[MPD()];
for (int i = 0; i < Score.size(); ++i)
cout << "[" << i << "] = " << Score[i] << endl;
}
這個程式只能用於 Win10 和 Win11,若要用於 Win7,可上網找一套 unassoc 1.4。
我這程式主要參考 删除Windows10后缀名关联程序.cpp ,其實那個程式已經足夠輕巧好用了。我寫的須要包裹一堆程式庫,有點大包。
我寫這程式的目的為了保留和測試一些技術。
原始檔案包,須用最新版 CxxlMan2 先建構好開發環境
Unassociate_File_Types_1.0.1_Src.7z
採用 CMake 方式編譯的執行檔無法在變更語言後自動調整版面,可用 CodeBlocks 載入 Src 資料夾中的 UnassocWin10.cbp 編譯一個來用
64位元版完整檔案包,可直接執行 UnassocWin10.exe
UnassocWin10_1.0.1.7z
另外程式支援多國語言,但能力有限只提供繁中語言檔,其他的語言會用內建的英語顯示,若有人願意轉譯他國語言,可到 MLedit 多國語言編輯器 下載工具,這 UnassocWin10 的多國誩言檔放在 Lang 資料夾中。
在這找到好辦法 C++ How to detect Windows 10 - Stack Overflow ,保留一份
#include <iostream>
#include <windows.h>
using namespace std;
// 回報 Windows 的版本 (7, 8, 8.1, 10)
double getSysOpType()
{
double ret = 0.0;
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
OSVERSIONINFOEXW osInfo;
*(FARPROC*)&RtlGetVersion =
GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
if (NULL != RtlGetVersion)
{
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion(&osInfo);
ret = (double)osInfo.dwMajorVersion;
}
return ret;
}
int main()
{
cout << getSysOpType() << endl;
return 0;
}
編輯 C++ 正則表達式須要不斷嘗式,網路上找到一個簡單的程式碼(一時找不到在哪看到)蠻不錯的,留一份在這
#include <iostream>
#include <regex>
using namespace std;
int main()
{
// regex reg("[\\.]|[\\b]+$");
//regex reg("([.]*)([\\.]+)([.]*)");
//regex reg(".*(\\.+).*");
//regex reg(".*(\\s$)");
//regex reg(".*(\\.+).*|.*(\\s$)");
//regex reg("[\\s]+");
regex reg("Applications\\\\.+_\\.bbbbb");
string input;
smatch sm;
while(true)
{
cout << "Enter: ";
getline(cin, input);
if(input == "quit")
break;
if( regex_match(input, sm , reg) )
{
cout << "Match!" << endl;
for( unsigned int i = 0 ; i < sm.size() ; ++i )
{
cout << i << ": [" << sm[i] << ']' << endl;
}
}
else
{
cout << "Not Match!" << endl;
}
}
return 0;
}
因 LearnOpenGL 採用 GLAD 來抓取 OpenGL API,所以也研究了一下,GLAD 的好處是可以明確指定你開發程式所要支援的 OpenGL 版本,在初始化時可以檢查顯示卡是否能支援。
GLAD 可到 https://glad.dav1d.de 下載,但拿到的會是原始檔,因 GLAD 只是把 OpenGL API 的函數位址抓出來存放到程式可觸及的記憶體空間中,若採用把 glad.c 和你的專案一起編譯,則主程式(exe) 和各用到 OpenGL API 的 dll 都得把 glad.c 一起編譯,並各別呼叫 gladLoadGL() 做初始化,既浪費空問(因得各別保存 OpenGL API 的函數位址)又沒人性(因得各別 gladLoadGL() 初始化)。
我想最完美的做法是把 GLAD 編譯成 dll,這樣 GLAD 的 OpenGL API 函數位址就放在這個 dll 獨立空間中,而 gladLoadGL() 只要由主程式呼叫一次就可以了。