mirror of
https://github.com/quantum5/Zalgo.git
synced 2025-04-24 05:31:58 -04:00
Initial Commit.
This commit is contained in:
commit
2d718e8ba5
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*.obj
|
||||
*.exe
|
||||
*.res
|
||||
/build
|
||||
/dist
|
||||
/temp
|
||||
/*.pdb
|
64
Makefile
Normal file
64
Makefile
Normal file
|
@ -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
|
13
include/Converter.hpp
Normal file
13
include/Converter.hpp
Normal file
|
@ -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
|
38
include/DropTarget.hpp
Normal file
38
include/DropTarget.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#ifndef idC4123BF1_C7A2_4DF3_AEA77895CE6309D9
|
||||
#define idC4123BF1_C7A2_4DF3_AEA77895CE6309D9
|
||||
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <oleidl.h>
|
||||
|
||||
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
|
37
include/MainWindow.hpp
Normal file
37
include/MainWindow.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
#ifndef id68C60171_0140_4DE1_B7255EFF557A74F9
|
||||
#define id68C60171_0140_4DE1_B7255EFF557A74F9
|
||||
|
||||
#include <Window.hpp>
|
||||
#include <MyDropTarget.hpp>
|
||||
#include <PreviewWindow.hpp>
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
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
|
17
include/MyDropTarget.hpp
Normal file
17
include/MyDropTarget.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#ifndef id8025A145_C3EF_4938_A70FBAFE9C2F9712
|
||||
#define id8025A145_C3EF_4938_A70FBAFE9C2F9712
|
||||
|
||||
#include <DropTarget.hpp>
|
||||
|
||||
#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
|
34
include/PreviewWindow.hpp
Normal file
34
include/PreviewWindow.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#ifndef id68C60174_0140_4DE1_B7255EFF557A74F9
|
||||
#define id68C60174_0140_4DE1_B7255EFF557A74F9
|
||||
|
||||
#include <Window.hpp>
|
||||
#include <MyDropTarget.hpp>
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#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
|
62
include/Window.hpp
Normal file
62
include/Window.hpp
Normal file
|
@ -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 <windows.h>
|
||||
|
||||
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
|
1
include/resource.h
Normal file
1
include/resource.h
Normal file
|
@ -0,0 +1 @@
|
|||
#define RID_ICON 1
|
86
src/Converter.cpp
Normal file
86
src/Converter.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <Converter.hpp>
|
||||
|
||||
typedef std::basic_string<wchar_t> 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;
|
||||
|
||||
}
|
91
src/DropTarget.cpp
Normal file
91
src/DropTarget.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <DropTarget.hpp>
|
||||
|
||||
HRESULT DropTarget::QueryInterface(REFIID iid, void **ppv)
|
||||
{
|
||||
if (iid == IID_IUnknown)
|
||||
*ppv = static_cast<IUnknown*>(this);
|
||||
else if (iid == IID_IDropTarget)
|
||||
*ppv = static_cast<IDropTarget*>(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;
|
||||
}
|
382
src/MainWindow.cpp
Normal file
382
src/MainWindow.cpp
Normal file
|
@ -0,0 +1,382 @@
|
|||
#include <MainWindow.hpp>
|
||||
#include <Converter.hpp>
|
||||
|
||||
#include <resource.h>
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <windowsx.h>
|
||||
#include <shlwapi.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#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;
|
||||
}
|
66
src/MyDropTarget.cpp
Normal file
66
src/MyDropTarget.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <MyDropTarget.hpp>
|
||||
#include <shellapi.h>
|
||||
|
||||
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;
|
||||
}
|
315
src/PreviewWindow.cpp
Normal file
315
src/PreviewWindow.cpp
Normal file
|
@ -0,0 +1,315 @@
|
|||
#include <PreviewWindow.hpp>
|
||||
#include <Converter.hpp>
|
||||
|
||||
#include <resource.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
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;
|
||||
}
|
88
src/Window.cpp
Normal file
88
src/Window.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include <window.hpp>
|
||||
|
||||
#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<HDC>(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);
|
||||
}
|
30
src/Zalgo.cpp
Normal file
30
src/Zalgo.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <MainWindow.hpp>
|
||||
#include <commctrl.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Reference in a new issue