From 2d718e8ba5adc0e0fe0bfee62cbd08a9130aae2c Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 30 Mar 2013 13:05:37 -0400 Subject: [PATCH] Initial Commit. --- .gitignore | 7 + Makefile | 64 +++++++ Zalgo.ico | Bin 0 -> 32350 bytes Zalgo.rc | 3 + include/Converter.hpp | 13 ++ include/DropTarget.hpp | 38 ++++ include/MainWindow.hpp | 37 ++++ include/MyDropTarget.hpp | 17 ++ include/PreviewWindow.hpp | 34 ++++ include/Window.hpp | 62 +++++++ include/resource.h | 1 + src/Converter.cpp | 86 +++++++++ src/DropTarget.cpp | 91 +++++++++ src/MainWindow.cpp | 382 ++++++++++++++++++++++++++++++++++++++ src/MyDropTarget.cpp | 66 +++++++ src/PreviewWindow.cpp | 315 +++++++++++++++++++++++++++++++ src/Window.cpp | 88 +++++++++ src/Zalgo.cpp | 30 +++ 18 files changed, 1334 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 Zalgo.ico create mode 100644 Zalgo.rc create mode 100644 include/Converter.hpp create mode 100644 include/DropTarget.hpp create mode 100644 include/MainWindow.hpp create mode 100644 include/MyDropTarget.hpp create mode 100644 include/PreviewWindow.hpp create mode 100644 include/Window.hpp create mode 100644 include/resource.h create mode 100644 src/Converter.cpp create mode 100644 src/DropTarget.cpp create mode 100644 src/MainWindow.cpp create mode 100644 src/MyDropTarget.cpp create mode 100644 src/PreviewWindow.cpp create mode 100644 src/Window.cpp create mode 100644 src/Zalgo.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..053bade --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.obj +*.exe +*.res +/build +/dist +/temp +/*.pdb diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5ce873e --- /dev/null +++ b/Makefile @@ -0,0 +1,64 @@ +SRCDIR=src +INCDIR=include + +CXX=cl /nologo +LD=link /nologo +CXXFLAGS=/c /I$(INCDIR) /W4 /Zi /DWIN32_LEAN_AND_MEAN /DWINVER=0x0501 /D_WIN32_WINNT=0x0501 /wd4100 /DUNICODE /D_UNICODE +LDFLAGS=/subsystem:windows /debug /manifest /incremental:no /opt:REF +LDFLAGS=$(LDFLAGS) "/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'" +RC=rc /nologo +RCFLAGS=/i$(INCDIR) +LIBS= + +!IFDEF DEBUG +BUILD=Debug +CXXFLAGS=$(CXXFLAGS) /DDEBUG +LDFLAGS=$(LDFLAGS) +!ELSE +BUILD=Release +LDFLAGS=$(LDFLAGS) +!ENDIF + +OUTDIR=build\$(BUILD) +DISTDIR=dist\$(BUILD) +FILES=$(OUTDIR)\Zalgo.obj \ + $(OUTDIR)\MainWindow.obj \ + $(OUTDIR)\Window.obj \ + $(OUTDIR)\DropTarget.obj \ + $(OUTDIR)\Converter.obj \ + $(OUTDIR)\PreviewWindow.obj \ + $(OUTDIR)\MyDropTarget.obj \ + $(OUTDIR)\Zalgo.res + +all: initdir $(DISTDIR)\Zalgo.exe + +initdir: + if not exist build md build + if not exist $(OUTDIR) md $(OUTDIR) + if not exist build md dist + if not exist $(DISTDIR) md $(DISTDIR) + +$(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)\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 + +$(OUTDIR)\Zalgo.res: Zalgo.rc + $(RC) $(RCFLAGS) /fo$@ $** + +{$(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/Zalgo.ico b/Zalgo.ico new file mode 100644 index 0000000000000000000000000000000000000000..7cf4934a37934558287550a23999f217863c7577 GIT binary patch literal 32350 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 + +RID_ICON ICON Zalgo.ico diff --git a/include/Converter.hpp b/include/Converter.hpp new file mode 100644 index 0000000..2b00167 --- /dev/null +++ b/include/Converter.hpp @@ -0,0 +1,13 @@ +#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/DropTarget.hpp b/include/DropTarget.hpp new file mode 100644 index 0000000..0351269 --- /dev/null +++ b/include/DropTarget.hpp @@ -0,0 +1,38 @@ +#pragma once +#ifndef idC4123BF1_C7A2_4DF3_AEA77895CE6309D9 +#define idC4123BF1_C7A2_4DF3_AEA77895CE6309D9 + +#include +#include +#include + +class DropTarget : public IDropTarget { +public: + IFACEMETHODIMP QueryInterface(REFIID iid, void **ppv); + IFACEMETHODIMP_(ULONG) STDMETHODCALLTYPE AddRef(void); + IFACEMETHODIMP_(ULONG) STDMETHODCALLTYPE Release(void); + IFACEMETHODIMP DragOver(DWORD dwState, POINTL pt, + DWORD *pdwEffect); + IFACEMETHODIMP DragEnter(IDataObject *pDataObject, DWORD dwState, POINTL pt, + DWORD *pdwEffect); + IFACEMETHODIMP DragLeave(void); + IFACEMETHODIMP Drop(IDataObject *pDataObject, DWORD dwState, POINTL pt, + DWORD *pdwEffect); + + STDMETHODIMP_(BOOL) DragDropRegister(HWND hwnd, DWORD dwState=MK_LBUTTON); + + virtual DWORD OnDragEnter(POINTL point, DWORD effect, DWORD state, + IDataObject *data); + virtual DWORD OnDragOver(POINTL point, DWORD effect, DWORD state); + virtual void OnDragLeave(void) {} + virtual DWORD OnDrop(POINTL point, DWORD effect, DWORD state, + IDataObject *data) = 0; + +protected: + HWND m_hwnd; + DWORD m_state; +private: + volatile ULONG m_ref; +}; + +#endif diff --git a/include/MainWindow.hpp b/include/MainWindow.hpp new file mode 100644 index 0000000..3b593b8 --- /dev/null +++ b/include/MainWindow.hpp @@ -0,0 +1,37 @@ +#pragma once +#ifndef id68C60171_0140_4DE1_B7255EFF557A74F9 +#define id68C60171_0140_4DE1_B7255EFF557A74F9 + +#include +#include +#include + +#include +#include + +class MainWindow : public Window { +public: + virtual LPCTSTR ClassName() { return TEXT("Zalgo_Main"); } + static MainWindow *Create(LPCTSTR szTitle); +protected: + LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT OnCreate(); + LRESULT OnDestroy(); + void OnPaint(); + + virtual HICON GetIcon(); + + 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; + MyDropTarget m_dropTarget; + PreviewWindow *m_preview; +private: + HFONT hFont, hFontMono; + HBRUSH hBrush; + UDACCEL *udaSecondAccel; +}; + +#endif // header diff --git a/include/MyDropTarget.hpp b/include/MyDropTarget.hpp new file mode 100644 index 0000000..c71bf49 --- /dev/null +++ b/include/MyDropTarget.hpp @@ -0,0 +1,17 @@ +#pragma once +#ifndef id8025A145_C3EF_4938_A70FBAFE9C2F9712 +#define id8025A145_C3EF_4938_A70FBAFE9C2F9712 + +#include + +#define WM_DROPTEXT (WM_USER+1) +#define WM_DROPFILE (WM_USER+2) + +class MyDropTarget : public DropTarget { + virtual DWORD OnDragEnter(POINTL point, DWORD effect, DWORD state, + IDataObject *data); + virtual DWORD OnDrop(POINTL point, DWORD effect, DWORD state, + IDataObject *data); +}; + +#endif diff --git a/include/PreviewWindow.hpp b/include/PreviewWindow.hpp new file mode 100644 index 0000000..e035f89 --- /dev/null +++ b/include/PreviewWindow.hpp @@ -0,0 +1,34 @@ +#pragma once +#ifndef id68C60174_0140_4DE1_B7255EFF557A74F9 +#define id68C60174_0140_4DE1_B7255EFF557A74F9 + +#include +#include + +#include +#include + +#define WM_CHANGETEXT (WM_USER+1) + +class PreviewWindow : public Window { +public: + virtual LPCTSTR ClassName() { return TEXT("Zalgo_Preview"); } + static PreviewWindow *Create(LPCTSTR szTitle); + void Destroy() { DestroyWindow(m_hwnd); } +protected: + LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT OnCreate(); + LRESULT OnDestroy(); + void OnPaint(); + + virtual HICON GetIcon(); +private: + HFONT hFont; + HBRUSH hBrush; + int xChar, yChar, xUpper, xClient, yClient, xClientMax, xPos, yPos; + LPTSTR *lpLines; + int lines; + bool empty; +}; + +#endif // header diff --git a/include/Window.hpp b/include/Window.hpp new file mode 100644 index 0000000..645b974 --- /dev/null +++ b/include/Window.hpp @@ -0,0 +1,62 @@ +#pragma once +#ifndef idC3714409_EABC_45DE_B5338EC60149AE87 +#define idC3714409_EABC_45DE_B5338EC60149AE87 + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +inline void MakeRect(RECT &rect, int x, int y, int cx, int cy) +{ + rect.left = x; + rect.top = y; + rect.right = x + cx; + rect.bottom = y + cy; +} + +inline void MakeRectRight(RECT &rect, int x, int y, int cx, int cy) +{ + MakeRect(rect, x - cx, y, cx, cy); +} + +inline void MakeRectBottom(RECT &rect, int x, int y, int cx, int cy) +{ + MakeRect(rect, x, y - cy, cx, cy); +} + +inline void MakeRectBottomRight(RECT &rect, int x, int y, int cx, int cy) +{ + MakeRect(rect, x - cx, y - cy, cx, cy); +} + +class Window { +public: + HWND GetHWND() { return m_hwnd; } + static HINSTANCE GetInstance() { return (HINSTANCE) GetModuleHandle(NULL); } +protected: + virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void PaintContent(PAINTSTRUCT *pps) {} + virtual LPCTSTR ClassName() = 0; + virtual HICON GetIcon() { return NULL; } + virtual BOOL WinRegisterClass(WNDCLASS *pwc) { + return RegisterClass(pwc); + } + virtual ~Window(); + + HWND WinCreateWindow(DWORD dwExStyle, LPCTSTR pszName, + DWORD dwStyle, int x, int y, int cx, + int cy, HWND hwndParent, HMENU hmenu); +private: + virtual void Register(); + void OnPaint(); + void OnPrintClient(HDC hdc); + + static LRESULT CALLBACK + s_WndProc(HWND hwnd, UINT uMsg, + WPARAM wParam, LPARAM lParam); +protected: + HWND m_hwnd; +}; + +#endif // header diff --git a/include/resource.h b/include/resource.h new file mode 100644 index 0000000..4501386 --- /dev/null +++ b/include/resource.h @@ -0,0 +1 @@ +#define RID_ICON 1 diff --git a/src/Converter.cpp b/src/Converter.cpp new file mode 100644 index 0000000..0f02e38 --- /dev/null +++ b/src/Converter.cpp @@ -0,0 +1,86 @@ +#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/DropTarget.cpp b/src/DropTarget.cpp new file mode 100644 index 0000000..0308d1c --- /dev/null +++ b/src/DropTarget.cpp @@ -0,0 +1,91 @@ +#include + +HRESULT DropTarget::QueryInterface(REFIID iid, void **ppv) +{ + if (iid == IID_IUnknown) + *ppv = static_cast(this); + else if (iid == IID_IDropTarget) + *ppv = static_cast(this); + else { + *ppv = NULL; + return E_NOINTERFACE; + } + this->AddRef(); + return S_OK; +} + +ULONG DropTarget::AddRef(void) +{ + return InterlockedIncrement(&m_ref); +} + +ULONG DropTarget::Release(void) +{ + ULONG ref = InterlockedDecrement(&m_ref); + if (ref == 0) + delete this; + return ref; +} + +BOOL DropTarget::DragDropRegister(HWND hwnd, DWORD dwState) +{ + m_hwnd = hwnd; + m_state = dwState; + return SUCCEEDED(RegisterDragDrop(hwnd, this)); +} + +HRESULT DropTarget::DragEnter(IDataObject *pDataObject, DWORD dwState, + POINTL pt, DWORD *pdwEffect) +{ + if (pdwEffect == NULL) + return E_INVALIDARG; // Thank you for trying to crash me + + if (dwState != m_state) { + *pdwEffect = DROPEFFECT_NONE; + return S_OK; + } + + *pdwEffect = OnDragEnter(pt, *pdwEffect, dwState, pDataObject); + return S_OK; +} + +HRESULT DropTarget::DragOver(DWORD dwState, POINTL pt, DWORD *pdwEffect) +{ + if (pdwEffect == NULL) + return E_INVALIDARG; // Thank you for trying to crash me + + if (dwState != m_state) { + *pdwEffect = DROPEFFECT_NONE; + return S_OK; + } + + *pdwEffect = OnDragOver(pt, *pdwEffect, dwState); + return S_OK; +} + +HRESULT DropTarget::DragLeave(void) +{ + OnDragLeave(); + return S_OK; +} + +HRESULT DropTarget::Drop(IDataObject *pDataObject, DWORD dwState, POINTL pt, + DWORD *pdwEffect) +{ + if (pdwEffect == NULL) + return E_INVALIDARG; // Thank you for trying to crash me + + *pdwEffect = OnDrop(pt, *pdwEffect, dwState, pDataObject); + return S_OK; +} + +DWORD DropTarget::OnDragEnter(POINTL point, DWORD effect, DWORD state, + IDataObject *data) +{ + return DROPEFFECT_COPY; +} + +DWORD DropTarget::OnDragOver(POINTL point, DWORD effect, DWORD state) +{ + return effect; +} diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp new file mode 100644 index 0000000..321e80c --- /dev/null +++ b/src/MainWindow.cpp @@ -0,0 +1,382 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define BGCOLOUR RGB(0xF0, 0xF0, 0xF0) +#define LEFT(x, y, cx, cy) x, y, cx, cy +#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 ZALGO_INITIAL (L"To invoke the hive-mind representing chaos.\r\n"\ + L"Invoking the feeling of chaos.\r\n"\ + L"With out order.\r\n"\ + L"The Nezperdian hive-mind of chaos. Zalgo.\r\n"\ + L"He who Waits Behind The Wall.\r\n"\ + L"ZALGO!\r\n\r\n"\ + L"WARNING: Resulting text size is roughly original "\ + L"* (1 + fuck up level). Thou hast been warned.\r\n"\ + L"\r\n"\ + L"NOTE: If this program crashes on thee, blame "\ + L"thyself for fucking up a piece of text that is too "\ + L"big with a very high fuck up level.\r\n\r\n"\ + L"Do blame Windows for not able to show proper text "\ + L"in the edit control, for now, use the preview "\ + L"button.\r\n\r\n"\ + L"Bonus Geek Info: NFD text will lose all "\ + L"diacritics. Thou hast been warned.\r\n") + +UINT ZALGO_MESS_LEVEL_[3] = {6, 10, 14}; +#define ZALGO_MESS_LEVEL_OF(type) (ZALGO_MESS_LEVEL_[type-0xDEAD]) + +#ifndef FNERR_INVALIDFILENAME +# define FNERR_INVALIDFILENAME 0x3002 +#endif + +#pragma comment(lib, "shlwapi.lib") +#pragma comment(lib, "shell32.lib") +#pragma comment(lib, "comctl32.lib") +#pragma comment(lib, "comdlg32.lib") + +WNDPROC wpOrigEditProc; + +LRESULT APIENTRY EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_KEYDOWN) { + if (wParam == L'A' && GetKeyState(VK_CONTROL) < 0) { + Edit_SetSel(hwnd, 0, -1); + return 0; + } + } + return CallWindowProc(wpOrigEditProc, hwnd, uMsg, + wParam, lParam); +} + +LRESULT MainWindow::OnCreate() +{ + NONCLIENTMETRICS ncmMetrics = { sizeof(NONCLIENTMETRICS) }; + RECT client; + + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncmMetrics, 0); + GetClientRect(m_hwnd, &client); + + hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont); + hBrush = CreateSolidBrush(BGCOLOUR); + 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); + m_goMiddle = CreateWindow(WC_BUTTON, L"fuck up the &middle", + WS_CHILDWINDOW | WS_VISIBLE | BS_CHECKBOX, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_GO_CENTER, GetInstance(), NULL); + 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", + 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); + m_messUpDown = CreateWindow(UPDOWN_CLASS, NULL, + 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); + m_unmess = CreateWindow(WC_BUTTON, L"HE &GOES!!!", + WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_HE_GOES, GetInstance(), NULL); + m_previewShow = CreateWindow(WC_BUTTON, L"&Preview", + WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, + m_hwnd, (HMENU) ZALGO_PREVIEW, 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) + SETFONT(m_message); + SETFONT(m_goUp); + SETFONT(m_goMiddle); + SETFONT(m_goDown); + SETFONT(m_messMini); + SETFONT(m_messNormal); + SETFONT(m_messMax); + SETFONT(m_messCustom); + SETFONT(m_messLevel); + SETFONT(m_mess); + SETFONT(m_unmess); + SETFONT(m_previewShow); +#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; +} + +LRESULT MainWindow::OnDestroy() +{ + SetWindowLongPtr(m_message, GWL_WNDPROC, (LONG_PTR) wpOrigEditProc); + + DestroyWindow(m_message); + DestroyWindow(m_goUp); + DestroyWindow(m_goMiddle); + DestroyWindow(m_goDown); + DestroyWindow(m_messMini); + DestroyWindow(m_messNormal); + DestroyWindow(m_messMax); + DestroyWindow(m_messCustom); + DestroyWindow(m_messLevel); + DestroyWindow(m_messUpDown); + DestroyWindow(m_mess); + DestroyWindow(m_unmess); + DestroyWindow(m_previewShow); + delete m_preview; + return 0; +} + +HICON MainWindow::GetIcon() +{ + return LoadIcon(GetInstance(), MAKEINTRESOURCE(RID_ICON)); +} + +void MainWindow::OnPaint() +{ + PAINTSTRUCT ps; + BeginPaint(m_hwnd, &ps); + PaintContent(&ps); + EndPaint(m_hwnd, &ps); +} + +LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_CREATE: + return OnCreate(); + case WM_DESTROY: + return OnDestroy(); + case WM_NCDESTROY: + PostQuitMessage(0); + break; + case WM_PAINT: + OnPaint(); + return 0; + case WM_SIZE: { + RECT client; + GetClientRect(m_hwnd, &client); +#define REPOS(hwnd, k) SetWindowPos(hwnd, 0, k, SWP_NOACTIVATE|SWP_NOZORDER) + REPOS(m_message, LEFT(12, 12, client.right - 24, client.bottom - 94)); + 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)); + REPOS(m_messMini, BOTTOM(160, client.bottom - 59, 120, 20)); + REPOS(m_messNormal, BOTTOM(160, client.bottom - 34, 120, 20)); + REPOS(m_messMax, BOTTOM(160, client.bottom - 9, 120, 20)); + REPOS(m_messCustom, BOTTOM(280, client.bottom - 59, 120, 20)); + REPOS(m_messLevel, BOTTOM(280, client.bottom - 34, 100, 20)); + REPOS(m_mess, BOTTOMRIGHT(client.right - 12, client.bottom - 41, 100, 25)); + REPOS(m_unmess, BOTTOMRIGHT(client.right - 12, client.bottom - 12, 100, 25)); + REPOS(m_previewShow,BOTTOMRIGHT(client.right - 117, client.bottom - 12, 100, 25)); +#undef REPOS + PostMessage(m_messUpDown, UDM_SETBUDDY, (WPARAM) m_messLevel, 0); + return 0; + } + case WM_COMMAND: + switch (HIWORD(wParam)) { + 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); + text = new wchar_t[textlen+1]; + Edit_GetText(m_message, text, textlen+1); + + zalgo = ZalgoComes(text, + IsDlgButtonChecked(m_hwnd, ZALGO_GO_UP), + IsDlgButtonChecked(m_hwnd, ZALGO_GO_CENTER), + IsDlgButtonChecked(m_hwnd, ZALGO_GO_DOWN), + 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); + 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); + zalgo = new wchar_t[textlen+1]; + Edit_GetText(m_message, zalgo, textlen+1); + + text = ZalgoGoes(zalgo); + + Edit_SetText(m_message, text); + + delete [] text; + delete [] zalgo; + } + + Button_Enable(m_mess, TRUE); + Button_Enable(m_unmess, TRUE); + break; + case ZALGO_PREVIEW: { + wchar_t *text; + int textlen; + textlen = Edit_GetTextLength(m_message); + 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 ZALGO_GO_UP: + case ZALGO_GO_CENTER: + case ZALGO_GO_DOWN: + Button_SetCheck((HWND) lParam, !IsDlgButtonChecked(m_hwnd, LOWORD(wParam))); + break; + default: + Button_SetCheck(GetDlgItem(m_hwnd, ZALGO_MINI_MESS), 0); + Button_SetCheck(GetDlgItem(m_hwnd, ZALGO_NORMAL_MESS), 0); + 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: + case ZALGO_MAX_MESS: + SetDlgItemInt(m_hwnd, ZALGO_MESS_LEVEL, + ZALGO_MESS_LEVEL_OF(LOWORD(wParam)), + FALSE); + Edit_Enable(m_messLevel, 0); + break; + case ZALGO_CUSTOM_MESS: + Edit_Enable(m_messLevel, 1); + } + } + break; + } + break; + case WM_CTLCOLORSTATIC: { + HBRUSH white = CreateSolidBrush(RGB(255, 255, 255)); + if ((HWND) lParam == m_messLevel && IsWindowEnabled(m_messLevel)) + return (LRESULT) white; + SetBkColor((HDC) wParam, BGCOLOUR); + return (LRESULT) hBrush; + } + case WM_KEYDOWN: + if (wParam == 'K' && GetKeyState(VK_CONTROL) < 0 && + GetKeyState(VK_SHIFT) < 0 && GetKeyState(VK_MENU) < 0) { + static bool unlocked = false; + // A user has tried to go beyond max, let is work + if (!unlocked && MessageBox(m_hwnd, L"\ +Thou hast tried to loosen my limits, dost thou promise that:\r\n\ + 1. thou will be responsible to use the string generated\r\n\ + 2. thou will be careful to not enter a number too large that will crash me\r\n\ + 3. if thou dost crash me, blame thyself for entering a number too large\r\n\ +\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; + } + break; + case WM_DROPTEXT: + SendMessage(m_message, EM_REPLACESEL, 0, lParam); + return 0; + case WM_DROPFILE: + //SetWindowText(m_script, (LPTSTR) lParam); + return 0; + } + return __super::HandleMessage(uMsg, wParam, lParam); +} + +MainWindow *MainWindow::Create(LPCTSTR szTitle) +{ + MainWindow *self = new MainWindow(); + if (self && + self->WinCreateWindow(0, + szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, + NULL, NULL)) { + return self; + } + delete self; + return NULL; +} diff --git a/src/MyDropTarget.cpp b/src/MyDropTarget.cpp new file mode 100644 index 0000000..1a45029 --- /dev/null +++ b/src/MyDropTarget.cpp @@ -0,0 +1,66 @@ +#include +#include + +DWORD MyDropTarget::OnDragEnter(POINTL point, DWORD effect, DWORD state, + IDataObject *data) +{ + FORMATETC format = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + + if (SUCCEEDED(data->QueryGetData(&format))) + return DROPEFFECT_COPY; + + format.cfFormat = CF_HDROP; + if (SUCCEEDED(data->QueryGetData(&format))) + return DROPEFFECT_COPY; + return DROPEFFECT_NONE; +} + +DWORD MyDropTarget::OnDrop(POINTL point, DWORD effect, DWORD state, + IDataObject *data) +{ + FORMATETC format = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + STGMEDIUM medium; + +#ifdef UNICODE + format.cfFormat = CF_UNICODETEXT; +#endif + { + if (FAILED(data->GetData(&format, &medium))) + goto ansi; + LPTSTR str = (LPTSTR) GlobalLock(medium.hGlobal); + SendMessage(m_hwnd, WM_DROPTEXT, 0, (LPARAM) str); + GlobalUnlock(medium.hGlobal); + return DROPEFFECT_COPY; + } + + ansi: +#ifdef UNICODE + { + format.cfFormat = CF_TEXT; + if (FAILED(data->GetData(&format, &medium))) + goto hdrop; + LPSTR str = (LPSTR) GlobalLock(medium.hGlobal); + DWORD dwLen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) + 1; + LPWSTR wstr = new WCHAR[dwLen]; + MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, dwLen); + SendMessage(m_hwnd, WM_DROPTEXT, 0, (LPARAM) wstr); + delete [] wstr; + GlobalUnlock(medium.hGlobal); + return DROPEFFECT_COPY; + } +#endif + + hdrop: + { + format.cfFormat = CF_HDROP; + if (FAILED(data->GetData(&format, &medium))) + goto fail; + TCHAR file[MAX_PATH] = {0}; + DragQueryFile((HDROP) medium.hGlobal, 0, file, MAX_PATH); + SendMessage(m_hwnd, WM_DROPFILE, (WPARAM) medium.hGlobal, (LPARAM) file); + return DROPEFFECT_COPY; + } + + fail: + return DROPEFFECT_NONE; +} diff --git a/src/PreviewWindow.cpp b/src/PreviewWindow.cpp new file mode 100644 index 0000000..be65448 --- /dev/null +++ b/src/PreviewWindow.cpp @@ -0,0 +1,315 @@ +#include +#include + +#include +#include + +LRESULT PreviewWindow::OnCreate() +{ + NONCLIENTMETRICS ncmMetrics = { sizeof(NONCLIENTMETRICS) }; + RECT client; + + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncmMetrics, 0); + GetClientRect(m_hwnd, &client); + + hFont = CreateFontIndirect(&ncmMetrics.lfMessageFont); + + // Get the handle to the client area's device context. + HDC hdc = GetDC(m_hwnd); + TEXTMETRIC tm; + // Extract font dimensions from the text metrics. + GetTextMetrics(hdc, &tm); + xChar = tm.tmAveCharWidth; + xUpper =(tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; + yChar = tm.tmHeight + tm.tmExternalLeading; + // Free the device context. + ReleaseDC(m_hwnd, hdc); + // Set an arbitrary maximum width for client area. + //(xClientMax is the sum of the widths of 48 average + // lowercase letters and 12 uppercase letters.) + xClientMax = 48 * xChar + 12 * xUpper; + + lpLines = NULL; + return 0; +} + +LRESULT PreviewWindow::OnDestroy() +{ + return 0; +} + +HICON PreviewWindow::GetIcon() +{ + return LoadIcon(GetInstance(), MAKEINTRESOURCE(RID_ICON)); +} + +void PreviewWindow::OnPaint() +{ + PAINTSTRUCT ps; + SCROLLINFO si; + RECT rect; + + BeginPaint(m_hwnd, &ps); + GetClientRect(m_hwnd, &rect); + + if (empty) + goto done; + + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + GetScrollInfo(m_hwnd, SB_VERT, &si); + yPos = si.nPos; + + SelectObject(ps.hdc, hFont); + SetBkColor(ps.hdc, RGB(0xF0, 0xF0, 0xF0)); + // Find painting limits. + int FirstLine = max(0, yPos + ps.rcPaint.top / yChar); + int LastLine = min(lines - 1, yPos + ps.rcPaint.bottom / yChar); + + // Get horizontal scroll bar position. + GetScrollInfo(m_hwnd, SB_HORZ, &si); + xPos = si.nPos; + for (int i = FirstLine; i <= LastLine; i++) { + int x = xChar *(1 - xPos); + int y = yChar *(i - yPos); + rect.top = y; + rect.left = x; + DrawText(ps.hdc, lpLines[i], -1, &rect, DT_NOCLIP); + } + done: + EndPaint(m_hwnd, &ps); +} + +LRESULT PreviewWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) { + case WM_CREATE: + return OnCreate(); + case WM_DESTROY: + return OnDestroy(); + case WM_NCDESTROY: + PostQuitMessage(0); + break; + case WM_PAINT: + OnPaint(); + return 0; + case WM_SIZE: { + RECT client; + SCROLLINFO si; + + GetClientRect(m_hwnd, &client); + yClient = client.bottom - client.top; + xClient = client.right - client.left; + + // Set the vertical scrolling range and page size + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + si.nMax = lines - 1; + si.nPage = yClient / yChar; + SetScrollInfo(m_hwnd, SB_VERT, &si, TRUE); + + // Set the horizontal scrolling range and page size. + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + si.nMax = 2 + xClientMax / xChar; + si.nPage = xClient / xChar; + SetScrollInfo(m_hwnd, SB_HORZ, &si, TRUE); + return 0; + } + case WM_HSCROLL: { + SCROLLINFO si; + // Get all the vertial scroll bar information. + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + + // Save the position for comparison later on. + GetScrollInfo(m_hwnd, SB_HORZ, &si); + xPos = si.nPos; + switch(LOWORD(wParam)) { + // User clicked the left arrow. + case SB_LINELEFT: + si.nPos -= 1; + break; + // User clicked the right arrow. + case SB_LINERIGHT: + si.nPos += 1; + break; + // User clicked the scroll bar shaft left of the scroll box. + case SB_PAGELEFT: + si.nPos -= si.nPage; + break; + // User clicked the scroll bar shaft right of the scroll box. + case SB_PAGERIGHT: + si.nPos += si.nPage; + break; + // User dragged the scroll box. + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + } + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(m_hwnd, SB_HORZ, &si, TRUE); + GetScrollInfo(m_hwnd, SB_HORZ, &si); + + // If the position has changed, scroll the window. + if(si.nPos != xPos) + ScrollWindow(m_hwnd, xChar *(xPos - si.nPos), 0, NULL, NULL); + return 0; + } + case WM_VSCROLL: { + SCROLLINFO si; + // Get all the vertial scroll bar information. + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(m_hwnd, SB_VERT, &si); + + // Save the position for comparison later on. + yPos = si.nPos; + switch(LOWORD(wParam)) { + // User clicked the HOME keyboard key. + case SB_TOP: + si.nPos = si.nMin; + break; + // User clicked the END keyboard key. + case SB_BOTTOM: + si.nPos = si.nMax; + break; + // User clicked the top arrow. + case SB_LINEUP: + si.nPos -= 1; + break; + // User clicked the bottom arrow. + case SB_LINEDOWN: + si.nPos += 1; + break; + // User clicked the scroll bar shaft above the scroll box. + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + // User clicked the scroll bar shaft below the scroll box. + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + // User dragged the scroll box. + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + } + // Set the position and then retrieve it. Due to adjustments + // by Windows it may not be the same as the value set. + si.fMask = SIF_POS; + SetScrollInfo(m_hwnd, SB_VERT, &si, TRUE); + GetScrollInfo(m_hwnd, SB_VERT, &si); + + // If the position has changed, scroll window and update it. + if(si.nPos != yPos) { + ScrollWindow(m_hwnd, 0, yChar *(yPos - si.nPos), NULL, NULL); + UpdateWindow(m_hwnd); + } + return 0; + } + case WM_MOUSEWHEEL: { + SCROLLINFO si; + // Get all the vertial scroll bar information. + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(m_hwnd, SB_VERT, &si); + yPos = si.nPos; + + si.nPos -= GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; + si.fMask = SIF_POS; + SetScrollInfo(m_hwnd, SB_VERT, &si, TRUE); + GetScrollInfo(m_hwnd, SB_VERT, &si); + + if(si.nPos != yPos) { + ScrollWindow(m_hwnd, 0, yChar *(yPos - si.nPos), NULL, NULL); + UpdateWindow(m_hwnd); + } + return 0; + } + case WM_CHANGETEXT: { + if (lpLines) { + for (int i = 0; i < lines; ++i) + delete [] lpLines[i]; + delete [] lpLines; + } + + LPTSTR str = (LPTSTR) lParam; + int l = 0, longest = 0, maxlen = 0; + + if (*str == L'\0') { + empty = true; + lpLines = NULL; + } else empty = false; + + while (*str++) + if (*str == L'\n') + ++l; + + if (*(str-1) != L'\n') + ++l; + + lines = l + 8; + lpLines = new LPTSTR[lines]; + for (int i = 0; i < 4; ++i) { + lpLines[i] = new TCHAR[1]; + lpLines[i][0] = L'\0'; + } + str = (LPTSTR) lParam; + for (int i = 0; i < l; ++i) { + LPTSTR start = str, end, buf; + int len; + while (*str++ != L'\n' && *(str-1) != L'\0'); + end = str - 1; + len = end - start; + if (len > maxlen) { + longest = i+4; + maxlen = len; + } + buf = new TCHAR[len + 1]; + memcpy(buf, start, len*sizeof(TCHAR)); + buf[len] = L'\0'; + lpLines[i+4] = buf; + } + for (int i = l + 4; i < lines; ++i) { + lpLines[i] = new TCHAR[1]; + lpLines[i][0] = L'\0'; + } + + int upper = 0, lower = 0; + for (LPTSTR i = lpLines[longest]; *i; ++i) { + if (isupper(*i)) + ++upper; + else if (!IsZalgo(*i)) + ++lower; + } + xClientMax = lower * xChar + upper * xUpper; + + PostMessage(m_hwnd, WM_SIZE, 0, 0); + return 0; + } + case WM_CLOSE: + ShowWindow(m_hwnd, SW_HIDE); + return 0; + } + + return __super::HandleMessage(uMsg, wParam, lParam); +} + +PreviewWindow *PreviewWindow::Create(LPCTSTR szTitle) +{ + PreviewWindow *self = new PreviewWindow(); + if(self && + self->WinCreateWindow(0, + szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, + NULL, NULL)) { + return self; + } + delete self; + return NULL; +} diff --git a/src/Window.cpp b/src/Window.cpp new file mode 100644 index 0000000..17815e5 --- /dev/null +++ b/src/Window.cpp @@ -0,0 +1,88 @@ +#include + +#pragma comment(lib, "user32.lib") +#pragma comment(lib, "gdi32.lib") + +HWND Window::WinCreateWindow(DWORD dwExStyle, LPCTSTR pszName, + DWORD dwStyle, int x, int y, int cx, + int cy, HWND hwndParent, HMENU hmenu) +{ + Register(); + return CreateWindowEx(dwExStyle, ClassName(), pszName, dwStyle, + x, y, cx, cy, hwndParent, hmenu, GetInstance(), + this); +} + +Window::~Window() {} + +void Window::Register() +{ + WNDCLASS wc; + wc.style = 0; + wc.lpfnWndProc = Window::s_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetInstance(); + wc.hIcon = GetIcon(); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = CreateSolidBrush(RGB(0xF0, 0xF0, 0xF0)); + wc.lpszMenuName = NULL; + wc.lpszClassName = ClassName(); + + WinRegisterClass(&wc); +} + +LRESULT CALLBACK +Window::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + Window *self; + if (uMsg == WM_NCCREATE) { + LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam; + self = (Window *)(lpcs->lpCreateParams); + self->m_hwnd = hwnd; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM) self); + } else { + self = (Window *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + } + if (self) { + return self->HandleMessage(uMsg, wParam, lParam); + } else { + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } +} + +LRESULT Window::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_NCDESTROY: { + LRESULT lres; + lres = DefWindowProc(m_hwnd, uMsg, wParam, lParam); + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); + delete this; + return lres; + } + case WM_PAINT: + OnPaint(); + return 0; + case WM_PRINTCLIENT: + OnPrintClient(reinterpret_cast(wParam)); + return 0; + } + return DefWindowProc(m_hwnd, uMsg, wParam, lParam); +} + +void Window::OnPaint() +{ + PAINTSTRUCT ps; + BeginPaint(m_hwnd, &ps); + PaintContent(&ps); + EndPaint(m_hwnd, &ps); +} + +void Window::OnPrintClient(HDC hdc) +{ + PAINTSTRUCT ps; + ps.hdc = hdc; + GetClientRect(m_hwnd, &ps.rcPaint); + PaintContent(&ps); +} diff --git a/src/Zalgo.cpp b/src/Zalgo.cpp new file mode 100644 index 0000000..0bfdd85 --- /dev/null +++ b/src/Zalgo.cpp @@ -0,0 +1,30 @@ +#include +#include +#include + +#pragma comment(lib, "comctl32.lib") +#pragma comment(lib, "ole32.lib") + +class COleInitialize { +public: + COleInitialize() : m_hr(OleInitialize(NULL)) { } + ~COleInitialize() { if (SUCCEEDED(m_hr)) OleUninitialize(); } + operator HRESULT() const { return m_hr; } + HRESULT m_hr; +}; + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { + COleInitialize oleInit; + InitCommonControls(); + + MainWindow *win = MainWindow::Create(L"Unicode Diacritic-Polluted Text Generator"); + if (win) { + ShowWindow(win->GetHWND(), nCmdShow); + MSG msg; + while (GetMessage(&msg, NULL, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return 0; +}