diff --git a/Makefile b/Makefile index 63c3200..fc9478f 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,9 @@ FILES=$(OUTDIR)\Zalgo.obj \ $(OUTDIR)\MainWindow.obj \ $(OUTDIR)\Window.obj \ $(OUTDIR)\DropTarget.obj \ - $(OUTDIR)\Converter.obj \ + $(OUTDIR)\MainLogic.obj \ $(OUTDIR)\PreviewWindow.obj \ + $(OUTDIR)\NLSWrap.obj \ $(OUTDIR)\MyDropTarget.obj \ $(OUTDIR)\Zalgo.res @@ -42,13 +43,14 @@ $(INCDIR)\MainWindow.hpp: $(INCDIR)\Window.hpp $(INCDIR)\MyDropTarget.hpp $(INCDIR)\PreviewWindow.hpp: $(INCDIR)\Window.hpp $(INCDIR)\MyDropTarget.hpp: $(INCDIR)\DropTarget.hpp -$(SRCDIR)\MainWindow.cpp: $(INCDIR)\MainWindow.hpp $(INCDIR)\Converter.hpp $(INCDIR)\PreviewWindow.hpp +$(SRCDIR)\MainWindow.cpp: $(INCDIR)\MainWindow.hpp $(INCDIR)\PreviewWindow.hpp $(SRCDIR)\DropTarget.cpp: $(INCDIR)\DropTarget.hpp $(SRCDIR)\MyDropTarget.cpp: $(INCDIR)\MyDropTarget.hpp $(SRCDIR)\Zalgo.cpp: $(INCDIR)\MainWindow.hpp $(SRCDIR)\PreviewWindow.cpp: $(INCDIR)\PreviewWindow.hpp -$(SRCDIR)\Converter.cpp: $(INCDIR)\Converter.hpp $(SRCDIR)\Window.cpp: $(INCDIR)\Window.hpp +$(SRCDIR)\NLSWrap.cpp: $(INCDIR)\NLSWrap.hpp +$(SRCDIR)\MainLogic.cpp: $(INCDIR)\MainWindow.hpp $(INCDIR)\NLSWrap.hpp $(OUTDIR)\Zalgo.res: Zalgo.rc $(RC) $(RCFLAGS) /fo$@ $** @@ -56,9 +58,6 @@ $(OUTDIR)\Zalgo.res: Zalgo.rc {$(SRCDIR)}.cpp{$(OUTDIR)}.obj:: $(CXX) $(CXXFLAGS) /Fo$(OUTDIR)\ /Fd$(OUTDIR)\ $< -{$(SRCDIR)}.c{$(OUTDIR)}.obj:: - $(CXX) $(CXXFLAGS) /Fo$(OUTDIR)\ /Fd$(OUTDIR)\ $< - $(DISTDIR)\Zalgo.exe: $(FILES) $(LD) /out:$@ $(LDFLAGS) $** $(LIBS) mt.exe -nologo -manifest $@.manifest -outputresource:$@;1 && del $@.manifest || set ERRORLEVEL=0 diff --git a/include/Converter.hpp b/include/Converter.hpp deleted file mode 100644 index 2b00167..0000000 --- a/include/Converter.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#ifndef id76AD7CF2_E519_495C_8C6B138352825E12 -#define id76AD7CF2_E519_495C_8C6B138352825E12 - -inline bool IsZalgo(wchar_t ch) -{ - return ch >= 0x0300 && ch < 0x0370 || ch == 0x489; -} - -wchar_t *ZalgoComes(const wchar_t *text, bool up, bool mid, bool down, int level); -wchar_t *ZalgoGoes(const wchar_t *zalgo); - -#endif diff --git a/include/MainWindow.hpp b/include/MainWindow.hpp index d358e5b..ae11d30 100644 --- a/include/MainWindow.hpp +++ b/include/MainWindow.hpp @@ -9,6 +9,24 @@ #include #include +#define ZALGO_GO_UP 0xAB01 +#define ZALGO_GO_CENTER 0xAB02 +#define ZALGO_GO_DOWN 0xAB03 +#define ZALGO_MINI_MESS 0xDEAD +#define ZALGO_NORMAL_MESS 0xDEAE +#define ZALGO_MAX_MESS 0xDEAF +#define ZALGO_CUSTOM_MESS 0xDEAC +#define ZALGO_MESS_LEVEL 0xDEAB +#define ZALGO_HE_COMES 0xBEEF +#define ZALGO_HE_GOES 0xBEEE +#define ZALGO_PREVIEW 0xBEED +#define ZALGO_MESSAGE 0xDEED +#define TEXT_TO_NFC 0xA551 +#define TEXT_TO_NFD 0xA552 +#define ZALGO_LATIN 0xA554 +#define ZALGO_CYRILLIC 0xA555 +#define ZALGO_GREEK 0xA556 + class MainWindow : public Window { public: virtual LPCTSTR ClassName() { return TEXT("Zalgo_Main"); } @@ -19,15 +37,23 @@ protected: LRESULT OnDestroy(); void OnPaint(); BOOL WinRegisterClass(WNDCLASS *pwc); - virtual HICON GetIcon(); - + + void OnZalgoComes(); + void OnZalgoGoes(); + void OnTextNFC(); + void OnTextNFD(); + void OnTextCyrillic(); + void OnTextLatin(); + void OnTextGreek(); + HWND m_message; HWND m_goUp, m_goMiddle, m_goDown; HWND m_messMini, m_messNormal, m_messMax, m_messCustom; HWND m_messLevel, m_messUpDown; HWND m_mess, m_unmess, m_previewShow; HWND m_nfc, m_nfd; + HWND m_latin, m_cyrillic, m_greek; MyDropTarget m_dropTarget; PreviewWindow *m_preview; private: diff --git a/include/NLSWrap.hpp b/include/NLSWrap.hpp index e20c209..bd6e194 100644 --- a/include/NLSWrap.hpp +++ b/include/NLSWrap.hpp @@ -2,37 +2,6 @@ #ifndef id8B5E818D_F6E4_43FA_889FF93BB24D8D62 #define id8B5E818D_F6E4_43FA_889FF93BB24D8D62 -typedef int (WINAPI *FN_NORMALIZESTRING)(UINT NormForm, LPCWSTR lpSrcString, - int cwSrcLength, LPWSTR lpDstString, - int cwDstLength); -FN_NORMALIZESTRING f_NormalizeString = NULL; - -inline void ZalgoNormalizeInit() -{ - HMODULE module = LoadLibrary(L"normaliz.dll"); - FARPROC proc = GetProcAddress(module, "NormalizeString"); - if (proc) - f_NormalizeString = (FN_NORMALIZESTRING) proc; -} - -inline UINT NormalizeStringForm(DWORD form) -{ - switch (form) { - case MAP_PRECOMPOSED: - return 0x1; // NormalizationC - case MAP_COMPOSITE: - return 0x2; // NormalizationD - default: - return 0; - } -} - -inline int ZalgoNormalizeString(DWORD form, LPCWSTR src, LPWSTR dst, int bufsize) -{ - if (f_NormalizeString) - return f_NormalizeString(NormalizeStringForm(form), src, -1, dst, bufsize); - else - return FoldString(form, src, -1, dst, bufsize); -} +int ZalgoNormalizeString(DWORD form, LPCWSTR src, LPWSTR dst, int bufsize); #endif // header diff --git a/src/Converter.cpp b/src/Converter.cpp deleted file mode 100644 index 0f02e38..0000000 --- a/src/Converter.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include - -#include - -typedef std::basic_string wstring; - -const wchar_t zalgo_up_[] = { - 0x030d, 0x030e, 0x0304, 0x0305, 0x033f, 0x0311, 0x0306, 0x0310, 0x0352, - 0x0357, 0x0351, 0x0307, 0x0308, 0x030a, 0x0342, 0x0343, 0x0344, 0x034a, - 0x034b, 0x034c, 0x0303, 0x0302, 0x030c, 0x0350, 0x0300, 0x0301, 0x030b, - 0x030f, 0x0312, 0x0313, 0x0314, 0x033d, 0x0309, 0x0363, 0x0364, 0x0365, - 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, - 0x036f, 0x033e, 0x035b, 0x0346, 0x031a, 0 -}; - -const wchar_t zalgo_down_[] = { - 0x0316, 0x0317, 0x0318, 0x0319, 0x031c, 0x031d, 0x031e, 0x031f, 0x0320, - 0x0324, 0x0325, 0x0326, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, - 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0339, 0x033a, 0x033b, 0x033c, - 0x0345, 0x0347, 0x0348, 0x0349, 0x034d, 0x034e, 0x0353, 0x0354, 0x0355, - 0x0356, 0x0359, 0x035a, 0x0323, 0 -}; - -const wchar_t zalgo_mid_[] = { - 0x0315, 0x031b, 0x0340, 0x0341, 0x0358, 0x0321, 0x0322, 0x0327, 0x0328, - 0x0334, 0x0335, 0x0336, 0x034f, 0x035c, 0x035d, 0x035e, 0x035f, 0x0360, - 0x0362, 0x0338, 0x0337, 0x0361, 0x0489, 0 -}; - -const wstring zalgo_up = zalgo_up_; -const wstring zalgo_down = zalgo_down_; -const wstring zalgo_mid = zalgo_mid_; - -inline int randint(int min, int max) -{ - if (min == max) - return min; - if (min >= max) - return 0; - return min + rand() % (max - min); -} - -inline wchar_t randchar(const wstring &str) -{ - return str[rand() % str.length()]; -} - -wchar_t *ZalgoComes(const wchar_t *text, bool up, bool mid, bool down, int level) -{ - wstring zalgo; - for (; *text; ++text) { - if (IsZalgo(*text)) - continue; - zalgo.push_back(*text); - if (*text < L' ') - continue; - int count_up = randint(level / 3, level), - count_mid = randint(level / 6, level / 2), - count_down = randint(level / 3, level); -#define IMPLEMENT_ZALGO(type) \ - if (type) {\ - for (int i = 0; i < count_##type; ++i) \ - zalgo.push_back(randchar(zalgo_##type)); \ - } - IMPLEMENT_ZALGO(up); - IMPLEMENT_ZALGO(mid); - IMPLEMENT_ZALGO(down); - } - wchar_t *out = new wchar_t[zalgo.length() + 1]; - StringCchCopy(out, zalgo.length() + 1, zalgo.c_str()); - return out; -} - -wchar_t *ZalgoGoes(const wchar_t *zalgo) -{ - wstring text; - for (; *zalgo; ++zalgo) - if (!IsZalgo(*zalgo)) - text += *zalgo; - wchar_t *out = new wchar_t[text.length() + 1]; - StringCchCopy(out, text.length() + 1, text.c_str()); - return out; - -} diff --git a/src/MainLogic.cpp b/src/MainLogic.cpp new file mode 100644 index 0000000..77518fc --- /dev/null +++ b/src/MainLogic.cpp @@ -0,0 +1,220 @@ +#include +#include +#include +#include + +#include +#include + + +typedef std::basic_string wstring; + +const wchar_t zalgo_up_[] = { + 0x030d, 0x030e, 0x0304, 0x0305, 0x033f, 0x0311, 0x0306, 0x0310, 0x0352, + 0x0357, 0x0351, 0x0307, 0x0308, 0x030a, 0x0342, 0x0343, 0x0344, 0x034a, + 0x034b, 0x034c, 0x0303, 0x0302, 0x030c, 0x0350, 0x0300, 0x0301, 0x030b, + 0x030f, 0x0312, 0x0313, 0x0314, 0x033d, 0x0309, 0x0363, 0x0364, 0x0365, + 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, + 0x036f, 0x033e, 0x035b, 0x0346, 0x031a, 0 +}; + +const wchar_t zalgo_down_[] = { + 0x0316, 0x0317, 0x0318, 0x0319, 0x031c, 0x031d, 0x031e, 0x031f, 0x0320, + 0x0324, 0x0325, 0x0326, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, + 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0339, 0x033a, 0x033b, 0x033c, + 0x0345, 0x0347, 0x0348, 0x0349, 0x034d, 0x034e, 0x0353, 0x0354, 0x0355, + 0x0356, 0x0359, 0x035a, 0x0323, 0 +}; + +const wchar_t zalgo_mid_[] = { + 0x0315, 0x031b, 0x0340, 0x0341, 0x0358, 0x0321, 0x0322, 0x0327, 0x0328, + 0x0334, 0x0335, 0x0336, 0x034f, 0x035c, 0x035d, 0x035e, 0x035f, 0x0360, + 0x0362, 0x0338, 0x0337, 0x0361, 0x0489, 0 +}; + +const wstring zalgo_up = zalgo_up_; +const wstring zalgo_down = zalgo_down_; +const wstring zalgo_mid = zalgo_mid_; + +const std::pair latin_cyrillic_[] = { + std::make_pair(L"a", 0x0430), std::make_pair(L"b", 0x0431), + std::make_pair(L"c", 0x0446), std::make_pair(L"ch", 0x0447), + std::make_pair(L"d", 0x0434), std::make_pair(L"e", 0x0435), + std::make_pair(L"f", 0x0444), std::make_pair(L"g", 0x0433), + std::make_pair(L"gh", 0x0445), std::make_pair(L"h", 0x0445), + std::make_pair(L"i", 0x0438), std::make_pair(L"j", 0x0439), + std::make_pair(L"k", 0x043A), std::make_pair(L"kh", 0x0445), + std::make_pair(L"l", 0x043B), std::make_pair(L"m", 0x043C), + std::make_pair(L"n", 0x043D), std::make_pair(L"o", 0x043E), + std::make_pair(L"p", 0x043F), std::make_pair(L"q", 0x043A), + std::make_pair(L"r", 0x0440), std::make_pair(L"s", 0x0441), + std::make_pair(L"sh", 0x0448), std::make_pair(L"t", 0x0442), + std::make_pair(L"ts", 0x0446), std::make_pair(L"u", 0x0443), + std::make_pair(L"v", 0x0432), std::make_pair(L"w", 0x0432), + std::make_pair(L"x", 0x0449), std::make_pair(L"y", 0x044B), + std::make_pair(L"ya", 0x044F), std::make_pair(L"z", 0x0437), + std::make_pair(L"zh", 0x0436), + std::make_pair(L"A", 0x0410), std::make_pair(L"B", 0x0411), + std::make_pair(L"C", 0x0426), std::make_pair(L"D", 0x0414), + std::make_pair(L"E", 0x0415), std::make_pair(L"F", 0x0424), + std::make_pair(L"G", 0x0413), std::make_pair(L"H", 0x0425), + std::make_pair(L"I", 0x0418), std::make_pair(L"J", 0x0419), + std::make_pair(L"K", 0x041A), std::make_pair(L"L", 0x041B), + std::make_pair(L"M", 0x041C), std::make_pair(L"N", 0x041D), + std::make_pair(L"O", 0x041E), std::make_pair(L"P", 0x041F), + std::make_pair(L"Q", 0x041A), std::make_pair(L"R", 0x0420), + std::make_pair(L"S", 0x0421), std::make_pair(L"T", 0x0422), + std::make_pair(L"U", 0x0423), std::make_pair(L"V", 0x0412), + std::make_pair(L"W", 0x0412), std::make_pair(L"X", 0x0429), + std::make_pair(L"Y", 0x042B), std::make_pair(L"Z", 0x0417), + std::make_pair(L"CH", 0x0427), std::make_pair(L"GH", 0x0425), + std::make_pair(L"KH", 0x0425), std::make_pair(L"SH", 0x0428), + std::make_pair(L"TS", 0x0426), std::make_pair(L"YA", 0x042F), + std::make_pair(L"ZH", 0x0416), + std::make_pair(L"Ch", 0x0427), std::make_pair(L"Gh", 0x0425), + std::make_pair(L"Kh", 0x0425), std::make_pair(L"Sh", 0x0428), + std::make_pair(L"Ts", 0x0426), std::make_pair(L"Ya", 0x042F), + std::make_pair(L"Zh", 0x0416), +}; + +const std::unordered_map latin_cyrillic(latin_cyrillic_, + latin_cyrillic_ + ARRAYSIZE(latin_cyrillic_)); + +inline int randint(int min, int max) +{ + if (min == max) + return min; + if (min >= max) + return 0; + return min + rand() % (max - min); +} + +inline wchar_t randchar(const wstring &str) +{ + return str[rand() % str.length()]; +} + +inline bool IsZalgo(wchar_t ch) +{ + return ch >= 0x0300 && ch < 0x0370 || ch == 0x489; +} + +void MainWindow::OnZalgoComes() +{ + HLOCAL buf = Edit_GetHandle(m_message); + wstring zalgo; + bool up = IsDlgButtonChecked(m_hwnd, ZALGO_GO_UP) != 0, + mid = IsDlgButtonChecked(m_hwnd, ZALGO_GO_CENTER) != 0, + down = IsDlgButtonChecked(m_hwnd, ZALGO_GO_DOWN) != 0; + int level = GetDlgItemInt(m_hwnd, ZALGO_MESS_LEVEL, NULL, FALSE); + LPWSTR text = (LPWSTR) LocalLock(buf); + + for (; *text; ++text) { + if (IsZalgo(*text)) + continue; + zalgo.push_back(*text); + if (*text < L' ') + continue; + int count_up = randint(level / 3, level), + count_mid = randint(level / 6, level / 2), + count_down = randint(level / 3, level); +#define IMPLEMENT_ZALGO(type) \ + if (type) {\ + for (int i = 0; i < count_##type; ++i) \ + zalgo.push_back(randchar(zalgo_##type)); \ + } + IMPLEMENT_ZALGO(up); + IMPLEMENT_ZALGO(mid); + IMPLEMENT_ZALGO(down); + } + LocalUnlock(buf); + Edit_SetText(m_message, zalgo.c_str()); +} + +void MainWindow::OnZalgoGoes() +{ + HLOCAL buf = Edit_GetHandle(m_message); + wstring text; + LPWSTR zalgo = (LPWSTR) LocalLock(buf); + + for (; *zalgo; ++zalgo) + if (!IsZalgo(*zalgo)) + text.push_back(*zalgo); + LocalUnlock(buf); + Edit_SetText(m_message, text.c_str()); +} + +#define ZALGO_NORMALIZE(name, type) \ + wchar_t *orig, *name = NULL; \ + int bufsize; \ + int textlen; \ + \ + textlen = Edit_GetTextLength(m_message) + 1; \ + orig = new wchar_t[textlen]; \ + Edit_GetText(m_message, orig, textlen); \ + \ + bufsize = ZalgoNormalizeString(type, orig, NULL, 0); \ + if (bufsize <= 0) \ + goto name##cleanup; \ + name = new wchar_t[bufsize]; \ + if (ZalgoNormalizeString(type, orig, name, bufsize) <= 0) \ + goto name##cleanup; \ + Edit_SetText(m_message, name); \ + \ + name##cleanup: \ + if (name) \ + delete name; \ + delete orig; + + +void MainWindow::OnTextNFC() +{ + ZALGO_NORMALIZE(nfc, MAP_PRECOMPOSED); +} + +void MainWindow::OnTextNFD() +{ + ZALGO_NORMALIZE(nfd, MAP_COMPOSITE); +} + +void MainWindow::OnTextCyrillic() +{ + HLOCAL buf = Edit_GetHandle(m_message); + wstring cyrillic, temp; + LPWSTR text = (LPWSTR) LocalLock(buf); + + for (; *text; ++text) { + temp = wstring(text, 2); + if (latin_cyrillic.count(temp)) { + cyrillic.push_back(latin_cyrillic.at(temp)); + ++text; + } else if (temp.pop_back(), latin_cyrillic.count(temp)) + cyrillic.push_back(latin_cyrillic.at(temp)); + else + cyrillic.push_back(*text); + + // shch handling + if (cyrillic.back() == 0x447 || cyrillic.back() == 0x427) { + wchar_t ch = cyrillic.back(); + cyrillic.pop_back(); + if (cyrillic.back() == 0x448) { + cyrillic.pop_back(); + cyrillic.push_back(0x449); + } else if (cyrillic.back() == 0x428) { + cyrillic.pop_back(); + cyrillic.push_back(0x429); + } else + cyrillic.push_back(ch); + } + } + LocalUnlock(buf); + Edit_SetText(m_message, cyrillic.c_str()); +} + +void MainWindow::OnTextLatin() +{ +} + +void MainWindow::OnTextGreek() +{ +} diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index e6d813a..a2e1fdc 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include @@ -15,20 +13,6 @@ #define RIGHT(x, y, cx, cy) (x - cx), y, cx, cy #define BOTTOM(x, y, cx, cy) x, (y - cy), cx, cy #define BOTTOMRIGHT(x, y, cx, cy) (x - cx), (y - cy), cx, cy -#define ZALGO_GO_UP 0xAB01 -#define ZALGO_GO_CENTER 0xAB02 -#define ZALGO_GO_DOWN 0xAB03 -#define ZALGO_MINI_MESS 0xDEAD -#define ZALGO_NORMAL_MESS 0xDEAE -#define ZALGO_MAX_MESS 0xDEAF -#define ZALGO_CUSTOM_MESS 0xDEAC -#define ZALGO_MESS_LEVEL 0xDEAB -#define ZALGO_HE_COMES 0xBEEF -#define ZALGO_HE_GOES 0xBEEE -#define ZALGO_PREVIEW 0xBEED -#define ZALGO_MESSAGE 0xDEED -#define TEXT_TO_NFC 0xA551 -#define TEXT_TO_NFD 0xA552 #define ZALGO_INITIAL (L"To invoke the hive-mind representing chaos.\r\n"\ L"Invoking the feeling of chaos.\r\n"\ @@ -88,20 +72,20 @@ LRESULT MainWindow::OnCreate() SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncmMetrics, 0); GetClientRect(m_hwnd, &client); - + hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont); hBrush = GetSysColorBrush(COLOR_WINDOW); rgbWindowBackground = GetSysColor(COLOR_WINDOW); hFontMono = CreateFont(0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FF_MODERN, TEXT("Consolas")); - + // Children m_message = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, ZALGO_INITIAL, WS_CHILDWINDOW | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_MESSAGE, GetInstance(), NULL); - + m_goUp = CreateWindow(WC_BUTTON, L"fuck up going &up", WS_CHILDWINDOW | WS_VISIBLE | BS_CHECKBOX, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_GO_UP, GetInstance(), NULL); @@ -111,20 +95,20 @@ LRESULT MainWindow::OnCreate() m_goDown = CreateWindow(WC_BUTTON, L"fuck up going &down", WS_CHILDWINDOW | WS_VISIBLE | BS_CHECKBOX, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_GO_DOWN, GetInstance(), NULL); - + m_messMini = CreateWindow(WC_BUTTON, L"m&ini fuck up", WS_CHILDWINDOW | WS_VISIBLE | BS_RADIOBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_MINI_MESS, GetInstance(), NULL); m_messNormal = CreateWindow(WC_BUTTON, L"&normal fuck up", WS_CHILDWINDOW | WS_VISIBLE | BS_RADIOBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_NORMAL_MESS, GetInstance(), NULL); - m_messMax = CreateWindow(WC_BUTTON, L"m&axi fuck up", + m_messMax = CreateWindow(WC_BUTTON, L"k&azi fuck up", WS_CHILDWINDOW | WS_VISIBLE | BS_RADIOBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_MAX_MESS, GetInstance(), NULL); m_messCustom = CreateWindow(WC_BUTTON, L"c&ustom fuck up", WS_CHILDWINDOW | WS_VISIBLE | BS_RADIOBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_CUSTOM_MESS, GetInstance(), NULL); - + m_messLevel = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL, WS_CHILDWINDOW | WS_VISIBLE | ES_NUMBER | ES_LEFT | ES_READONLY, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_MESS_LEVEL, GetInstance(), NULL); @@ -132,7 +116,7 @@ LRESULT MainWindow::OnCreate() WS_CHILDWINDOW | WS_VISIBLE | UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK, 0, 0, 0, 0, m_hwnd, NULL, GetInstance(), NULL); - + m_mess = CreateWindow(WC_BUTTON, L"HE &COMES!!!", WS_CHILDWINDOW | WS_VISIBLE | BS_DEFPUSHBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_HE_COMES, GetInstance(), NULL); @@ -142,7 +126,7 @@ LRESULT MainWindow::OnCreate() m_previewShow = CreateWindow(WC_BUTTON, L"&Preview", WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) ZALGO_PREVIEW, GetInstance(), NULL); - + m_nfc = CreateWindow(WC_BUTTON, L"N&FC", WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) TEXT_TO_NFC, GetInstance(), NULL); @@ -150,6 +134,16 @@ LRESULT MainWindow::OnCreate() WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, m_hwnd, (HMENU) TEXT_TO_NFD, GetInstance(), NULL); + m_latin = CreateWindow(WC_BUTTON, L"Use &Latin", + WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_LATIN, GetInstance(), NULL); + m_cyrillic = CreateWindow(WC_BUTTON, L"Use C&yrillic", + WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_CYRILLIC, GetInstance(), NULL); + m_greek = CreateWindow(WC_BUTTON, L"Use G&reek", + WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_GREEK, GetInstance(), NULL); + PostMessage(m_messUpDown, UDM_SETRANGE32, 1, ZALGO_MESS_LEVEL_OF(ZALGO_MAX_MESS)); PostMessage(m_messUpDown, UDM_SETPOS32, 0, ZALGO_MESS_LEVEL_OF(ZALGO_NORMAL_MESS)); #define SETFONT(hwnd) PostMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM) FALSE) @@ -167,24 +161,27 @@ LRESULT MainWindow::OnCreate() SETFONT(m_previewShow); SETFONT(m_nfc); SETFONT(m_nfd); + SETFONT(m_latin); + SETFONT(m_cyrillic); + SETFONT(m_greek); #undef SETFONT - + Button_SetCheck(m_goUp, 1); Button_SetCheck(m_goMiddle, 1); Button_SetCheck(m_goDown, 1); Button_SetCheck(m_messNormal, 1); Edit_Enable(m_messLevel, 0); - + if (!m_dropTarget.DragDropRegister(m_hwnd)) MessageBox(m_hwnd, TEXT("Failed to register Drag and Drop handler"), TEXT("Zalgo has COME!!!"), MB_ICONERROR); - + m_preview = PreviewWindow::Create(L"Text Preview"); - + // Subclassing wpOrigEditProc = (WNDPROC) SetWindowLongPtr(m_message, GWL_WNDPROC, (LONG_PTR) EditSubclassProc); - + return 0; } @@ -207,6 +204,9 @@ LRESULT MainWindow::OnDestroy() DestroyWindow(m_previewShow); DestroyWindow(m_nfc); DestroyWindow(m_nfd); + DestroyWindow(m_latin); + DestroyWindow(m_cyrillic); + DestroyWindow(m_greek); delete m_preview; return 0; } @@ -243,7 +243,7 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) GetClientRect(m_hwnd, &client); #define REPOS(hwnd, k) hdwp = DeferWindowPos(hdwp, hwnd, 0, k, SWP_NOACTIVATE|SWP_NOZORDER) hdwp = BeginDeferWindowPos(14); - REPOS(m_message, LEFT(12, 12, client.right - 24, client.bottom - 94)); + REPOS(m_message, LEFT(12, 12, client.right - 24, client.bottom - 124)); REPOS(m_goUp, BOTTOM(12, client.bottom - 59, 140, 20)); REPOS(m_goMiddle, BOTTOM(12, client.bottom - 34, 140, 20)); REPOS(m_goDown, BOTTOM(12, client.bottom - 9, 140, 20)); @@ -257,6 +257,9 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) REPOS(m_nfc, BOTTOMRIGHT(client.right - 117, client.bottom - 41, 50, 25)); REPOS(m_nfd, BOTTOMRIGHT(client.right - 117, client.bottom - 12, 50, 25)); REPOS(m_previewShow,BOTTOMRIGHT(client.right - 172, client.bottom - 12, 100, 25)); + REPOS(m_latin, BOTTOM(12, client.bottom - 84, 100, 25)); + REPOS(m_cyrillic, BOTTOM(117, client.bottom - 84, 100, 25)); + REPOS(m_greek, BOTTOM(222, client.bottom - 84, 100, 25)); EndDeferWindowPos(hdwp); #undef REPOS PostMessage(m_messUpDown, UDM_SETBUDDY, (WPARAM) m_messLevel, 0); @@ -267,56 +270,10 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) case BN_CLICKED: switch (LOWORD(wParam)) { case ZALGO_HE_COMES: - Button_Enable(m_mess, FALSE); - Button_Enable(m_unmess, FALSE); - - { - wchar_t *text; - int textlen; - wchar_t *zalgo; - - textlen = Edit_GetTextLength(m_message) + 1; - text = new wchar_t[textlen]; - Edit_GetText(m_message, text, textlen); - - zalgo = ZalgoComes(text, - IsDlgButtonChecked(m_hwnd, ZALGO_GO_UP) != 0, - IsDlgButtonChecked(m_hwnd, ZALGO_GO_CENTER) != 0, - IsDlgButtonChecked(m_hwnd, ZALGO_GO_DOWN) != 0, - GetDlgItemInt(m_hwnd, ZALGO_MESS_LEVEL, NULL, FALSE)); - - Edit_SetText(m_message, zalgo); - - delete [] zalgo; - delete [] text; - } - - Button_Enable(m_mess, TRUE); - Button_Enable(m_unmess, TRUE); + OnZalgoComes(); break; case ZALGO_HE_GOES: - Button_Enable(m_mess, FALSE); - Button_Enable(m_unmess, FALSE); - - { - wchar_t *text; - int textlen; - wchar_t *zalgo; - - textlen = Edit_GetTextLength(m_message) + 1; - zalgo = new wchar_t[textlen]; - Edit_GetText(m_message, zalgo, textlen); - - text = ZalgoGoes(zalgo); - - Edit_SetText(m_message, text); - - delete [] text; - delete [] zalgo; - } - - Button_Enable(m_mess, TRUE); - Button_Enable(m_unmess, TRUE); + OnZalgoGoes(); break; case ZALGO_PREVIEW: { wchar_t *text; @@ -324,56 +281,25 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) textlen = Edit_GetTextLength(m_message) + 1; text = new wchar_t[textlen]; Edit_GetText(m_message, text, textlen); - + SendMessage(m_preview->GetHWND(), WM_CHANGETEXT, 0, (LPARAM) text); ShowWindow(m_preview->GetHWND(), SW_SHOW); } - case TEXT_TO_NFC: { - wchar_t *orig, *nfc = NULL; - int bufsize; - int textlen; - - textlen = Edit_GetTextLength(m_message) + 1; - orig = new wchar_t[textlen]; - Edit_GetText(m_message, orig, textlen); - - bufsize = ZalgoNormalizeString(MAP_PRECOMPOSED, orig, NULL, 0); - if (bufsize <= 0) - goto nfccleanup; - nfc = new wchar_t[bufsize]; - if (ZalgoNormalizeString(MAP_PRECOMPOSED, orig, nfc, bufsize) <= 0) - goto nfccleanup; - Edit_SetText(m_message, nfc); - - nfccleanup: - if (nfc) - delete nfc; - delete orig; + case TEXT_TO_NFC: + OnTextNFC(); break; - } - case TEXT_TO_NFD: { - wchar_t *orig, *nfd = NULL; - int bufsize; - int textlen; - - textlen = Edit_GetTextLength(m_message) + 1; - orig = new wchar_t[textlen]; - Edit_GetText(m_message, orig, textlen); - - bufsize = ZalgoNormalizeString(MAP_COMPOSITE, orig, NULL, 0); - if (bufsize <= 0) - goto nfdcleanup; - nfd = new wchar_t[bufsize]; - if (ZalgoNormalizeString(MAP_COMPOSITE, orig, nfd, bufsize) <= 0) - goto nfdcleanup; - Edit_SetText(m_message, nfd); - - nfdcleanup: - if (nfd) - delete nfd; - delete orig; + case TEXT_TO_NFD: + OnTextNFD(); + break; + case ZALGO_LATIN: + OnTextLatin(); + break; + case ZALGO_CYRILLIC: + OnTextCyrillic(); + break; + case ZALGO_GREEK: + OnTextGreek(); break; - } case ZALGO_GO_UP: case ZALGO_GO_CENTER: case ZALGO_GO_DOWN: @@ -385,7 +311,7 @@ LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) Button_SetCheck(GetDlgItem(m_hwnd, ZALGO_MAX_MESS), 0); Button_SetCheck(GetDlgItem(m_hwnd, ZALGO_CUSTOM_MESS), 0); Button_SetCheck((HWND) lParam, 1); - + switch (LOWORD(wParam)) { case ZALGO_MINI_MESS: case ZALGO_NORMAL_MESS: @@ -423,7 +349,7 @@ Thou hast tried to loosen my limits, dost thou promise that:\r\n\ Dost thou agree?", L"About to Unlock Secret", MB_YESNO | MB_ICONQUESTION) == IDYES) { PostMessage(m_messUpDown, UDM_SETRANGE32, 1, LONG_MAX); PostMessage(m_messLevel, EM_SETREADONLY, 0, 0); - + unlocked = true; } return 0; @@ -432,8 +358,11 @@ Dost thou agree?", L"About to Unlock Secret", MB_YESNO | MB_ICONQUESTION) == IDY case WM_DROPTEXT: SendMessage(m_message, EM_REPLACESEL, 0, lParam); return 0; - case WM_DROPFILE: - //SetWindowText(m_script, (LPTSTR) lParam); + case WM_ENTERSIZEMOVE: + SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) | WS_EX_COMPOSITED); + return 0; + case WM_EXITSIZEMOVE: + SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) & ~WS_EX_COMPOSITED); return 0; } return __super::HandleMessage(uMsg, wParam, lParam); @@ -443,7 +372,7 @@ MainWindow *MainWindow::Create(LPCTSTR szTitle) { MainWindow *self = new MainWindow(); if (self && - self->WinCreateWindow(WS_EX_COMPOSITED, + self->WinCreateWindow(0, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL)) { diff --git a/src/NLSWrap.cpp b/src/NLSWrap.cpp new file mode 100644 index 0000000..b4a59f0 --- /dev/null +++ b/src/NLSWrap.cpp @@ -0,0 +1,27 @@ +#include + +typedef int (WINAPI *FN_NORMALIZESTRING)(UINT NormForm, LPCWSTR lpSrcString, + int cwSrcLength, LPWSTR lpDstString, + int cwDstLength); +FN_NORMALIZESTRING f_NormalizeString = (FN_NORMALIZESTRING) + GetProcAddress(LoadLibrary(L"normaliz.dll"), "NormalizeString"); + +UINT NormalizeStringForm(DWORD form) +{ + switch (form) { + case MAP_PRECOMPOSED: + return 0x1; // NormalizationC + case MAP_COMPOSITE: + return 0x2; // NormalizationD + default: + return 0; + } +} + +int ZalgoNormalizeString(DWORD form, LPCWSTR src, LPWSTR dst, int bufsize) +{ + if (f_NormalizeString) + return f_NormalizeString(NormalizeStringForm(form), src, -1, dst, bufsize); + else + return FoldString(form, src, -1, dst, bufsize); +} diff --git a/src/PreviewWindow.cpp b/src/PreviewWindow.cpp index be65448..271e1c6 100644 --- a/src/PreviewWindow.cpp +++ b/src/PreviewWindow.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -284,7 +283,7 @@ LRESULT PreviewWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) for (LPTSTR i = lpLines[longest]; *i; ++i) { if (isupper(*i)) ++upper; - else if (!IsZalgo(*i)) + else if (!(*i >= 0x0300 && *i < 0x0370 || *i == 0x489)) ++lower; } xClientMax = lower * xChar + upper * xUpper;