Skip to content

Instantly share code, notes, and snippets.

@LusainKim
Last active August 29, 2015 14:28
Show Gist options
  • Save LusainKim/ce35fc78a18dfebd061b to your computer and use it in GitHub Desktop.
Save LusainKim/ce35fc78a18dfebd061b to your computer and use it in GitHub Desktop.
LusDef
#include <Windows.h>
#include "LusDef.h"
////////////////////////////////////////////////
//
void DrawLineBox(HDC mainDC, RECT rc,
COLORREF main_RGB, COLORREF Line_RGB, int LineLen, bool Type)
{
SetDCBrushColor(mainDC, main_RGB);
FillRect(mainDC, &rc, (HBRUSH)GetStockObject(DC_BRUSH));
rc = SizeDown(rc, LineLen);
SetDCBrushColor(mainDC, Line_RGB);
FrameRect(mainDC, &rc, (HBRUSH)GetStockObject(DC_BRUSH));
if (Type == true)
{
rc = SizeDown(rc, 2);
FillRect(mainDC, &rc, (HBRUSH)GetStockObject(DC_BRUSH));
}
}
void FixValue(LPWSTR DestMsg, int fixnum)
{
// 초기값 0
TCHAR Fix[20] = L"0\0";
// 반한될 문자열
TCHAR returnMsg[20];
int count = 0;
int endnum;
while (fixnum > 0)
{
endnum = fixnum % 10;
fixnum /= 10;
Fix[count] = '0' + endnum;
count++;
if (count % 4 == 3 && fixnum > 0)
{
Fix[count] = ',';
count++;
}
}
if (count == 0) count++;
for (int i = 0; i < count; i++)
returnMsg[i] = Fix[count - i - 1];
returnMsg[count] = '\0';
lstrcpy(DestMsg, returnMsg);
}
//////////////////////////////////////////////////////////////////////////////////////////////
#define MsgBlank 5
#define MsgWidth 160
#define ButtonHeight 35
LusMsg Lus_MsgStorage;
LusInputMsg Lus_InputBoxStorage;
bool Flag_LusMsgBox;
HWND hLMg;
TCHAR Lus_strMsg[4096];
TCHAR Lus_strMsg_1[128];
TCHAR Lus_strMsg_2[128];
int iMsgAlpha;
void close_LusMsgProc()
{
DestroyWindow(hLMg);
hLMg = nullptr;
}
///////////////////////////////////////////////
// LusMsg Proc
LRESULT CALLBACK LusMsgProc(HWND hMsg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Msg
static LusMsg Msg;
const static LusMsg nullMsg;
static RECT rc_Msg_1, rc_Msg_2;
static int sel_Msg = 0;
static bool IsSel = false;
// Draw Vaule
PAINTSTRUCT ps;
HDC hdc;
// calc Value
RECT wndRect;
// Move Pointer
static POINT Mp, old_pt, pt_for_drag;
static bool flag_for_Drag;
GetWindowRect(hMsg, &wndRect);
POINT pt_for_wndFix = { -wndRect.left, -wndRect.top };
wndRect = wndRect + pt_for_wndFix;
switch (uMsg)
{
case WM_CREATE:
flag_for_Drag = false;
Msg = nullMsg;
sel_Msg = 0;
Mp = old_pt = pt_for_drag = { 0, 0 };
IsSel = false;
Flag_LusMsgBox = true;
break;
case WM_GETVALUE:
switch (wParam)
{
case wGETMSG:
Msg = Lus_MsgStorage;
Lus_MsgStorage = nullMsg;
if (Msg.bUseMsg_2)
{
rc_Msg_1 = {
MsgBlank + 2,
Msg.MsgSize.bottom - ButtonHeight - 4 - MsgBlank,
MsgBlank + 2 + (Msg.MsgSize.right - 2 * MsgBlank - 4) / 2,
Msg.MsgSize.bottom - 2 - MsgBlank
};
rc_Msg_2 = {
rc_Msg_1.right,
Msg.MsgSize.bottom - ButtonHeight - 4 - MsgBlank,
Msg.MsgSize.right - (MsgBlank + 2),
Msg.MsgSize.bottom - 2 - MsgBlank
};
}
else
{
rc_Msg_1 = {
MsgBlank + 2,
Msg.MsgSize.bottom - ButtonHeight - 4 - MsgBlank,
Msg.MsgSize.right - (MsgBlank + 2),
Msg.MsgSize.bottom - 2 - MsgBlank
};
}
break;
}
break;
case WM_LBUTTONDOWN:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
IsSel = false;
sel_Msg = 0;
// 따로 함수로 빼야함...
if (PtInRect(&rc_Msg_1, Mp))
{
sel_Msg = 1;
IsSel = true;
InvalidateRect(hMsg, NULL, false);
break;
}
else if (PtInRect(&rc_Msg_2, Mp))
{
sel_Msg = 2;
IsSel = true;
InvalidateRect(hMsg, NULL, false);
break;
}
flag_for_Drag = true;
ReleaseCapture();
SetCapture(hMsg);
GetCursorPos(&Mp);
pt_for_drag = old_pt = Mp;
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
old_pt = old_pt - Mp;
break;
case WM_MOUSEMOVE:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
if (flag_for_Drag)
{
GetCursorPos(&Mp);
old_pt.x = old_pt.x + Mp.x - pt_for_drag.x;
old_pt.y = old_pt.y + Mp.y - pt_for_drag.y;
SetWindowPos(hMsg, 0,
old_pt.x, old_pt.y,
0, 0, SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER);
pt_for_drag = Mp;
sel_Msg = 0;
break;
}
if (IsSel)
if (PtInRect(&rc_Msg_1, Mp))
sel_Msg = 1;
else if (PtInRect(&rc_Msg_2, Mp))
sel_Msg = 2;
else
sel_Msg = 0;
InvalidateRect(hMsg, NULL, false);
break;
case WM_LBUTTONUP:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
flag_for_Drag = false;
ReleaseCapture();
if (!IsSel) break;
IsSel = false;
sel_Msg = 0;
InvalidateRect(hMsg, NULL, false);
if (PtInRect(&rc_Msg_1, Mp))
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
(Msg.Msg_1_Func)(Msg.thisClass);
break;
}
else if (Msg.bUseMsg_2 && PtInRect(&rc_Msg_2, Mp))
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.Msg_2_Func(Msg.thisClass);
break;
}
break;
case WM_RBUTTONDOWN:
if (Msg.bUseMsg_2)
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.Msg_2_Func(Msg.thisClass);
break;
}
else
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.Msg_1_Func(Msg.thisClass);
break;
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_SPACE:
case VK_RETURN:
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
(Msg.Msg_1_Func)(Msg.thisClass);
break;
case VK_ESCAPE:
if (Msg.bUseMsg_2)
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.Msg_2_Func(Msg.thisClass);
}
else
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
(Msg.Msg_1_Func)(Msg.thisClass);
}
break;
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hMsg, &ps);
HDC LayDC = CreateCompatibleDC(hdc);
HBITMAP Lay = CreateCompatibleBitmap(hdc, wndRect.right, wndRect.bottom);
SelectObject(LayDC, Lay);
HFONT mainFont = CreateFont((Msg.FontSize == -1) ? DEFAULT_FontSize : Msg.FontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial ");
SelectObject(LayDC, mainFont);
SetTextColor(LayDC, Msg.TextColor);
SelectObject(LayDC, (HPEN)GetStockObject(WHITE_PEN));
SetBkMode(LayDC, TRANSPARENT);
RECT lprc;
TEXTMETRIC tm;
GetTextMetrics(LayDC, &tm);
int fontSize = tm.tmHeight;
SetDCBrushColor(LayDC, Msg.MsgColor);
FillRect(LayDC, &wndRect, (HBRUSH)GetStockObject(DC_BRUSH));
lprc = SizeDown(wndRect, MsgBlank);
FrameRect(LayDC, &lprc, (HBRUSH)GetStockObject(WHITE_BRUSH));
lprc = { MsgBlank + 2, MsgBlank + 2,
Msg.MsgSize.right - MsgBlank - 2, lprc.top + fontSize + 2 };
DrawText(LayDC, Msg.Title, -1, &lprc, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
MoveToEx(LayDC, MsgBlank + 1, lprc.bottom, NULL);
LineTo(LayDC, Msg.MsgSize.right - MsgBlank - 1, lprc.bottom);
lprc = { MsgBlank + 2, lprc.bottom + 2,
Msg.MsgSize.right - MsgBlank - 2,
Msg.MsgSize.bottom - ButtonHeight - 2 };
DrawText(LayDC, Msg.Msg, -1, &lprc,
DT_CENTER | DT_VCENTER | DT_WORDBREAK);
lprc = SizeDown(rc_Msg_1, 1);
DrawLineBox(LayDC, lprc, Msg.MsgColor, LusColor::White, MsgBlank, DL_FRAME);
if (sel_Msg == 1)
{
lprc = SizeDown(lprc, 4);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = 0;
bf.SourceConstantAlpha = ALPHA_SELECT;
HBITMAP blendLay = CreateCompatibleBitmap(LayDC, 10, 10);
HDC blendDC = CreateCompatibleDC(LayDC);
SelectObject(blendDC, blendLay);
SetDCBrushColor(blendDC, LusColor::White);
RECT rc_for_blend = { 0, 0, 10, 10 };
FillRect(blendDC, &rc_for_blend, (HBRUSH)GetStockObject(DC_BRUSH));
AlphaBlend(LayDC, lprc.left, lprc.top,
lprc.right - lprc.left, lprc.bottom - lprc.top, blendDC, 0, 0, 10, 10, bf);
DeleteDC(blendDC);
DeleteObject(blendLay);
}
DrawText(LayDC, Msg.InBoxMsg_1, -1, &lprc,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
if (Msg.bUseMsg_2)
{
lprc = SizeDown(rc_Msg_2, 1);
DrawLineBox(LayDC, lprc, Msg.MsgColor, LusColor::White, MsgBlank, DL_FRAME);
if (sel_Msg == 2)
{
lprc = SizeDown(lprc, 4);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = 0;
bf.SourceConstantAlpha = ALPHA_SELECT;
HBITMAP blendLay = CreateCompatibleBitmap(LayDC, 10, 10);
HDC blendDC = CreateCompatibleDC(LayDC);
SelectObject(blendDC, blendLay);
SetDCBrushColor(blendDC, LusColor::White);
RECT rc_for_blend = { 0, 0, 10, 10 };
FillRect(blendDC, &rc_for_blend, (HBRUSH)GetStockObject(DC_BRUSH));
AlphaBlend(LayDC, lprc.left, lprc.top,
lprc.right - lprc.left, lprc.bottom - lprc.top, blendDC, 0, 0, 10, 10, bf);
DeleteDC(blendDC);
DeleteObject(blendLay);
}
DrawText(LayDC, Msg.InBoxMsg_2, -1, &lprc,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
BitBlt(hdc, 0, 0, wndRect.right, wndRect.bottom, LayDC, 0, 0, SRCCOPY);
DeleteObject(mainFont);
DeleteObject(Lay);
DeleteDC(LayDC);
EndPaint(hMsg, &ps);
}
break;
case WM_DESTROY:
break;
default:
return DefWindowProc(hMsg, uMsg, wParam, lParam);
}
return 0;
}
void LusMsgBox(HWND hWnd, LusMsg Msg, HINSTANCE g_hInst, int alpha_message)
{
static WNDCLASSEX wc;
static bool Flag_first_Register = false;
int msgWidth = 300;
int msgHeight = 200;
RECT wndRect;
GetWindowRect(hWnd, &wndRect);
POINT wndcenter = { wndRect.right / 2, wndRect.bottom / 2 };
if (hLMg)
{
DestroyWindow(hLMg);
hLMg = nullptr;
}
LusMsg SendMsg = Msg;
if (!SendMsg.bUseMsg_2)
SendMsg.InBoxMsg_2 = L"";
int MsgLen = max(
lstrlen(SendMsg.Msg) + 2 * MsgBlank + 4,
lstrlen(SendMsg.InBoxMsg_1) + lstrlen(SendMsg.InBoxMsg_2) + 3 * MsgBlank + 6
);
if (sideCheck(0, MsgLen, 100))
{
msgWidth = MsgWidth;
msgHeight = 100;
}
else if (sideCheck(100, MsgLen, 200))
{
msgWidth = 250;
msgHeight = 125;
}
else if (sideCheck(200, MsgLen, 1000))
{
msgWidth = 300;
msgHeight = 200;
}
SendMsg.MsgSize.right = max(SendMsg.MsgSize.right, msgWidth);
// SendMsg.mainDC ;
// SendMsg.MsgSize;
// SendMsg.MsgStartPos;
// SendMsg.Title;
// SendMsg.Msg;
// SendMsg.Font;
// SendMsg.InBoxMsgNum;
// SendMsg.InBoxMsg_1;
// SendMsg.InBoxMsg_2;
// SendMsg.TextColor;
// Msg Height Init
{
HDC hdc, LayDC;
hdc = GetDC(NULL);
LayDC = CreateCompatibleDC(hdc);
HBITMAP Lay = CreateCompatibleBitmap(LayDC, 1, 1);
SelectObject(LayDC, Lay);
HFONT mainFont = CreateFont((SendMsg.FontSize == -1) ? DEFAULT_FontSize : SendMsg.FontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial ");
SelectObject(LayDC, mainFont);
RECT lprc = {
MsgBlank + 2,
0,
SendMsg.MsgSize.right - MsgBlank - 2,
1000 };
TEXTMETRIC tm;
GetTextMetrics(LayDC, &tm);
int fontSize = tm.tmHeight;
int AdjHeight =
DrawText(LayDC, SendMsg.Msg, -1, &lprc, DT_LEFT | DT_WORDBREAK) +
(MsgBlank * 2 + fontSize + ButtonHeight + 8);
DrawTextEx(LayDC, SendMsg.Msg, -1, &lprc,
DT_CALCRECT, nullptr);
if (abs(lprc.right + 4 + MsgBlank * 4 - msgWidth) < 46)
{
SendMsg.MsgSize.right = max(msgWidth, lprc.right + 4 + MsgBlank * 4);
AdjHeight =
lprc.bottom + (MsgBlank * 2 + fontSize + ButtonHeight + 8);
SendMsg.MsgSize.bottom = max(msgHeight, AdjHeight);
}
else
SendMsg.MsgSize.bottom = max(msgHeight, AdjHeight);
// lprc = SendMsg.MsgSize;
DeleteObject(mainFont);
ReleaseDC(NULL, hdc);
ReleaseDC(NULL, LayDC);
DeleteObject(Lay);
}
if (!Flag_first_Register)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = LusMsgProc;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszClassName = TEXT("LusMsgClass");
RegisterClassEx(&wc);
}
RECT getClientSize;
GetWindowRect(SendMsg.hWnd, &getClientSize);
hLMg = CreateWindow(wc.lpszClassName, NULL, WS_POPUP | WS_VISIBLE,
getClientSize.left + SendMsg.MsgStartPos.x - SendMsg.MsgSize.right / 2,
getClientSize.top + SendMsg.MsgStartPos.y - SendMsg.MsgSize.bottom / 2,
SendMsg.MsgSize.right, SendMsg.MsgSize.bottom, hWnd, NULL, g_hInst, NULL);
SetWindowLong(hLMg, GWL_EXSTYLE,
GetWindowLong(hLMg, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hLMg, 0, alpha_message, LWA_ALPHA);
iMsgAlpha = alpha_message;
Lus_MsgStorage = SendMsg;
SendMessage(hLMg, WM_GETVALUE, wGETMSG, 0);
EnableWindow(SendMsg.hWnd, false);
}
///////////////////////////////////////////////
// InputBox Proc
LRESULT CALLBACK LusInputMsgProc(HWND hMsg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Msg
static LusInputMsg Msg;
const static LusInputMsg nullMsg;
static RECT rc_Msg_1, rc_Msg_2;
static int sel_Msg = 0;
static bool IsSel = false;
static SIZE Csize;
static RECT rc_Insert;
// Draw Vaule
PAINTSTRUCT ps;
HDC hdc;
// calc Value
RECT wndRect;
// Move Pointer
static POINT Mp, old_pt, pt_for_drag;
static bool flag_for_Drag;
GetWindowRect(hMsg, &wndRect);
POINT pt_for_wndFix = { -wndRect.left, -wndRect.top };
wndRect = wndRect + pt_for_wndFix;
switch (uMsg)
{
case WM_CREATE:
CreateCaret(hMsg, NULL, 1, 15);
flag_for_Drag = false;
Msg = nullMsg;
sel_Msg = 0;
Mp = old_pt = pt_for_drag = { 0, 0 };
IsSel = false;
Flag_LusMsgBox = true;
break;
case WM_GETVALUE:
switch (wParam)
{
case wGETMSG:
Msg = Lus_InputBoxStorage;
Lus_InputBoxStorage = nullMsg;
HDC hdc = GetDC(Msg.hWnd);
HFONT mainFont = CreateFont((Msg.FontSize == -1) ? DEFAULT_FontSize : Msg.FontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial ");
SelectObject(hdc, mainFont);
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
int fontSize = tm.tmHeight;
RECT font_rc = { 0, 0, 1000, 1000 };
DrawText(hdc, (lstrlen(Msg.YesBox) > lstrlen(Msg.NoBox)) ? Msg.YesBox : Msg.NoBox, -1,
&font_rc, DT_CALCRECT);
rc_Msg_1 = {
Msg.MsgSize.right - (MsgBlank + 4) - font_rc.right - 16,
MsgBlank + fontSize + 6,
Msg.MsgSize.right - (MsgBlank + 2),
MsgBlank + fontSize + 6 + ButtonHeight
};
rc_Msg_2 = {
Msg.MsgSize.right - (MsgBlank + 4) - font_rc.right - 16,
rc_Msg_1.bottom + 2,
Msg.MsgSize.right - (MsgBlank + 2),
rc_Msg_1.bottom + 2 + ButtonHeight
};
DeleteObject(mainFont);
ReleaseDC(Msg.hWnd, hdc);
rc_Insert = { MsgBlank + 4, Msg.MsgSize.bottom - ButtonHeight,
Msg.MsgSize.right - MsgBlank - 4, Msg.MsgSize.bottom - (MsgBlank + 4) };
break;
}
break;
case WM_LBUTTONDOWN:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
IsSel = false;
sel_Msg = 0;
if (PtInRect(&rc_Insert, Mp))
{
SetCaretPos(Csize.cx + rc_Insert.left + 5, rc_Insert.top + Csize.cy / 2);
ShowCaret(hMsg);
break;
}
else
HideCaret(hMsg);
// 따로 함수로 빼야함...
if (PtInRect(&rc_Msg_1, Mp))
{
sel_Msg = 1;
IsSel = true;
InvalidateRect(hMsg, NULL, false);
break;
}
else if (PtInRect(&rc_Msg_2, Mp))
{
sel_Msg = 2;
IsSel = true;
InvalidateRect(hMsg, NULL, false);
break;
}
flag_for_Drag = true;
SetCapture(hMsg);
GetCursorPos(&Mp);
pt_for_drag = old_pt = Mp;
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
old_pt = old_pt - Mp;
break;
case WM_MOUSEMOVE:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
if (flag_for_Drag)
{
GetCursorPos(&Mp);
old_pt.x = old_pt.x + Mp.x - pt_for_drag.x;
old_pt.y = old_pt.y + Mp.y - pt_for_drag.y;
SetWindowPos(hMsg, 0,
old_pt.x, old_pt.y,
0, 0, SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER);
pt_for_drag = Mp;
sel_Msg = 0;
break;
}
if (IsSel == true)
if (PtInRect(&rc_Msg_1, Mp))
sel_Msg = 1;
else if (PtInRect(&rc_Msg_2, Mp))
sel_Msg = 2;
else
sel_Msg = 0;
InvalidateRect(hMsg, NULL, false);
break;
case WM_LBUTTONUP:
Mp.x = LOWORD(lParam);
Mp.y = HIWORD(lParam);
flag_for_Drag = false;
ReleaseCapture();
if (!IsSel) break;
sel_Msg = 0;
IsSel = false;
InvalidateRect(hMsg, NULL, false);
if (PtInRect(&rc_Msg_1, Mp))
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
(Msg.resultFunc)(Msg.thisClass, Msg.BoxValue);
break;
}
else if (PtInRect(&rc_Msg_2, Mp))
{
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.undoFunc(Msg.thisClass);
break;
}
break;
case WM_RBUTTONDOWN:
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.undoFunc(Msg.thisClass);
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_RETURN:
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
(Msg.resultFunc)(Msg.thisClass, Msg.BoxValue);
break;
case VK_ESCAPE:
SetWindowPos(Msg.hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
SetWindowPos(Msg.hWnd, HWND_DESKTOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
EnableWindow(Msg.hWnd, true);
Flag_LusMsgBox = false;
Msg.undoFunc(Msg.thisClass);
break;
}
break;
case WM_CHAR:
int len_BoxValue;
len_BoxValue = lstrlen(Msg.BoxValue);
if (len_BoxValue < Msg.InputMax && (
sideCheck(48, wParam, 58) || wParam > 65))
{
if (Msg.IsOnlyUseNum && wParam > 65) break;
Msg.BoxValue[len_BoxValue] = wParam;//입력받은값은wParam에있습니다.
Msg.BoxValue[len_BoxValue + 1] = 0;
SendMessage(hMsg, WM_PAINT, wParam, lParam);
SetCaretPos(Csize.cx + rc_Insert.left + 5, rc_Insert.top + Csize.cy / 2);
ShowCaret(hMsg);
InvalidateRect(hMsg, NULL, false);
break;
}
if (wParam == 8)
{
if (len_BoxValue > 0)
Msg.BoxValue[len_BoxValue - 1] = NULL;
SendMessage(hMsg, WM_PAINT, wParam, lParam);
SetCaretPos(Csize.cx + rc_Insert.left + 5, rc_Insert.top + Csize.cy / 2);
ShowCaret(hMsg);
InvalidateRect(hMsg, NULL, false);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hMsg, &ps);
HDC LayDC = CreateCompatibleDC(hdc);
HBITMAP Lay = CreateCompatibleBitmap(hdc, wndRect.right, wndRect.bottom);
SelectObject(LayDC, Lay);
HFONT mainFont = CreateFont((Msg.FontSize == -1) ? DEFAULT_FontSize : Msg.FontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial ");
SelectObject(LayDC, mainFont);
SetTextColor(LayDC, Msg.TextColor);
SelectObject(LayDC, (HPEN)GetStockObject(WHITE_PEN));
SetBkMode(LayDC, TRANSPARENT);
RECT lprc;
TEXTMETRIC tm;
GetTextMetrics(LayDC, &tm);
int fontSize = tm.tmHeight;
SetDCBrushColor(LayDC, Msg.MsgColor);
FillRect(LayDC, &wndRect, (HBRUSH)GetStockObject(DC_BRUSH));
lprc = SizeDown(wndRect, MsgBlank);
FrameRect(LayDC, &lprc, (HBRUSH)GetStockObject(WHITE_BRUSH));
lprc = { MsgBlank + 2, MsgBlank + 2,
Msg.MsgSize.right - MsgBlank - 2, lprc.top + fontSize + 2 };
DrawText(LayDC, Msg.Title, -1, &lprc, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
MoveToEx(LayDC, MsgBlank + 1, lprc.bottom, NULL);
LineTo(LayDC, Msg.MsgSize.right - MsgBlank - 1, lprc.bottom);
lprc = { MsgBlank + 2, lprc.bottom + 2,
rc_Msg_1.left - 2,
Msg.MsgSize.bottom - ButtonHeight - 2 };
DrawText(LayDC, Msg.Msg, -1, &lprc,
DT_CENTER | DT_VCENTER | DT_WORDBREAK);
lprc = SizeDown(rc_Msg_1, 1);
DrawLineBox(LayDC, lprc, Msg.MsgColor, LusColor::White, 1, DL_FRAME);
if (sel_Msg == 1)
{
lprc = SizeDown(lprc, 4);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = 0;
bf.SourceConstantAlpha = ALPHA_SELECT;
HBITMAP blendLay = CreateCompatibleBitmap(LayDC, 10, 10);
HDC blendDC = CreateCompatibleDC(LayDC);
SelectObject(blendDC, blendLay);
SetDCBrushColor(blendDC, LusColor::White);
RECT rc_for_blend = { 0, 0, 10, 10 };
FillRect(blendDC, &rc_for_blend, (HBRUSH)GetStockObject(DC_BRUSH));
AlphaBlend(LayDC, lprc.left, lprc.top,
lprc.right - lprc.left, lprc.bottom - lprc.top, blendDC, 0, 0, 10, 10, bf);
DeleteDC(blendDC);
DeleteObject(blendLay);
}
DrawText(LayDC, Msg.YesBox, -1, &lprc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
lprc = SizeDown(rc_Msg_2, 1);
DrawLineBox(LayDC, lprc, Msg.MsgColor, LusColor::White, 1, DL_FRAME);
if (sel_Msg == 2)
{
lprc = SizeDown(lprc, 4);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = 0;
bf.SourceConstantAlpha = ALPHA_SELECT;
HBITMAP blendLay = CreateCompatibleBitmap(LayDC, 10, 10);
HDC blendDC = CreateCompatibleDC(LayDC);
SelectObject(blendDC, blendLay);
SetDCBrushColor(blendDC, LusColor::White);
RECT rc_for_blend = { 0, 0, 10, 10 };
FillRect(blendDC, &rc_for_blend, (HBRUSH)GetStockObject(DC_BRUSH));
AlphaBlend(LayDC, lprc.left, lprc.top,
lprc.right - lprc.left, lprc.bottom - lprc.top, blendDC, 0, 0, 10, 10, bf);
DeleteDC(blendDC);
DeleteObject(blendLay);
}
DrawText(LayDC, Msg.NoBox, -1, &lprc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
FillRect(LayDC, &rc_Insert, (HBRUSH)GetStockObject(WHITE_BRUSH));
GetTextExtentPoint32(LayDC, Msg.BoxValue, lstrlen(Msg.BoxValue), &Csize);
lprc = rc_Insert + MakePoint(5, 0);
SetTextColor(LayDC, Msg.MsgColor);
DrawText(LayDC, Msg.BoxValue, -1, &lprc, DT_VCENTER | DT_SINGLELINE);
BitBlt(hdc, 0, 0, wndRect.right, wndRect.bottom, LayDC, 0, 0, SRCCOPY);
DeleteObject(mainFont);
DeleteObject(Lay);
DeleteDC(LayDC);
EndPaint(hMsg, &ps);
}
break;
case WM_DESTROY:
break;
default:
return DefWindowProc(hMsg, uMsg, wParam, lParam);
}
return 0;
}
void LusInputMsgBox(HWND hWnd, LusInputMsg Msg, HINSTANCE g_hInst, int alpha_message)
{
static WNDCLASSEX wc;
static bool Flag_first_Register = false;
int msgWidth = 100;
int msgHeight = 100;
RECT wndRect;
GetWindowRect(hWnd, &wndRect);
POINT wndcenter = { wndRect.right / 2, wndRect.bottom / 2 };
if (hLMg)
{
DestroyWindow(hLMg);
hLMg = nullptr;
}
LusInputMsg SendMsg = Msg;
SendMsg.MsgSize.right = max(SendMsg.MsgSize.right, msgWidth);
// Msg Height Init
{
HDC hdc, LayDC;
hdc = GetDC(NULL);
LayDC = CreateCompatibleDC(hdc);
HBITMAP Lay = CreateCompatibleBitmap(LayDC, 1, 1);
SelectObject(LayDC, Lay);
HFONT mainFont = CreateFont((SendMsg.FontSize == -1) ? DEFAULT_FontSize : SendMsg.FontSize, 0, 0, 0, 700, FALSE, FALSE, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial ");
SelectObject(LayDC, mainFont);
RECT font_rc = { 0, 0, 1000, 1000 };
DrawText(hdc, (lstrlen(Msg.YesBox) > lstrlen(Msg.NoBox)) ? Msg.YesBox : Msg.NoBox, -1,
&font_rc, DT_CALCRECT);
font_rc.right += 16;
RECT lprc = {
MsgBlank + 2,
0,
max(100, SendMsg.MsgSize.right - (MsgBlank + 6) - font_rc.right),
1000 };
TEXTMETRIC tm;
GetTextMetrics(LayDC, &tm);
int fontSize = tm.tmHeight;
int AdjHeight =
max(MsgBlank + fontSize + 14 + ButtonHeight, DrawText(LayDC, SendMsg.Msg, -1, &lprc, DT_LEFT | DT_WORDBREAK)) +
(MsgBlank * 2 + fontSize + ButtonHeight + 8);
//
DrawTextEx(LayDC, SendMsg.Msg, -1, &lprc, DT_CALCRECT, nullptr);
SendMsg.MsgSize.bottom = max(msgHeight, AdjHeight);
SendMsg.MsgSize.right = max(SendMsg.MsgSize.right + MsgBlank + 2, 2 * MsgBlank + 4 + SendMsg.InputSize);
// lprc = SendMsg.MsgSize;
DeleteObject(mainFont);
ReleaseDC(NULL, hdc);
ReleaseDC(NULL, LayDC);
DeleteObject(Lay);
}
if (!Flag_first_Register)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = LusInputMsgProc;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszClassName = TEXT("LusInputClass");
RegisterClassEx(&wc);
}
RECT getClientSize;
GetWindowRect(SendMsg.hWnd, &getClientSize);
hLMg = CreateWindow(wc.lpszClassName, NULL, WS_POPUP | WS_VISIBLE,
getClientSize.left + SendMsg.MsgStartPos.x - SendMsg.MsgSize.right / 2,
getClientSize.top + SendMsg.MsgStartPos.y - SendMsg.MsgSize.bottom / 2,
SendMsg.MsgSize.right, SendMsg.MsgSize.bottom, hWnd, NULL, g_hInst, NULL);
SetWindowLong(hLMg, GWL_EXSTYLE,
GetWindowLong(hLMg, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hLMg, 0, alpha_message, LWA_ALPHA);
Lus_InputBoxStorage = SendMsg;
SendMessage(hLMg, WM_GETVALUE, wGETMSG, 0);
EnableWindow(SendMsg.hWnd, false);
}
#pragma once
/*
* LusMsg 사용하기 :
*
1. 클래스로 사용하기
// 선언. Initialize 해야 동작을 보장합니다.
CLusMsg LMsg;
// WM_CREATE에
LMsg.Initialize(hWnd, hInst);
// 메세지박스를 호출 시
// 마스터클래스, 문자열 등은 가이드입니다. define으로 지정되어있지만 기능하지 않습니다.
LMsg.CreateMessageBox(
마스터클래스 &LMsg,
문자열 L"Test",
문자열 L"본문입니다.",
문자열 L"확인",
람다 [](void* Class){
메세지종료
static_cast<CLusMsg*>(Class)->CreateMessageBox(Class,
L"Test", L"확인 완료", L"종료", [](void* Class){
close_LusMsgProc();
});
},
선택지추가사용여부 true,
문자열 L"취소",
람다 [](void* Class){
메세지종료
}
);
2. 구조체를 사용하기(해당 코드에 모두 주석이 존재하므로 참조하시면 됩니다)
LusMsg Msg;
Msg.hWnd = hWnd;
Msg.Title = L"Test";
Msg.Msg = L"본문입니다.";
Msg.InBoxMsg_1 = L"확인";
Msg.thisClass = nullptr;
Msg.Msg_1_Func = [](void* Class){
메세지종료;
// 아래 코드로 인자로 넘겨받은 인자를 사용 가능
// static_cast<Typename *>(Class) ;
};
Msg.bUseMsg_2 = false;
LusMsgBox(Msg.hWnd, Msg, hInst, 175);
*
*
*/
/*
* LusInputMsg 사용하기 :
*
LusInputMsg는 문자열을 적을 건지, 숫자를 적을건지 선택해야합니다.
또한, InputMax로 문자열의 한계도 정할 수 있습니다.
resultFunc 인자에 람다를 이용하여 두 개의 인자를 넘겨주는데,
하나는 외부 정보를 가진 Class와 입력받은 값을 가진 output입니다.
또한, 아무것도 하지 않았을 경우에는 undoFunc을 호출합니다.
LusInputMsg Msg;
Msg.hWnd = hWnd;
Msg.MsgSize = MakeRect(0, 0, DEFAULT_MSGWIDTH, NULL);
Msg.MsgStartPos = GetCenterPos(hWnd);
Msg.Title = L"Test";
Msg.Msg = L"숫자를 적고 반환받을 수 있는 메세지박스입니다. ";
Msg.InputSize = 200;
Msg.YesBox = L" 확인 ";
Msg.NoBox = L" 취소 ";
Msg.TextColor = LusColor::White;
Msg.InputMax = 15;
Msg.IsOnlyUseNum = true;
Msg.MsgColor = RGB(125, 125, 125);
Msg.resultFunc = [](void *Class, TCHAR *output){
int rValue = _wtoi(output);
close_LusMsgProc();
LusMsg Msg;
Msg.hWnd = (HWND)Class;
Msg.MsgStartPos = GetCenterPos((HWND)Class);
Msg.Title = L"Test";
Msg.Msg = output;
Msg.InBoxMsg_1 = L"확인";
Msg.thisClass = nullptr;
Msg.Msg_1_Func = [](void* Class){
메세지종료;
// 아래 코드로 인자로 넘겨받은 인자를 사용 가능
// static_cast<Typename*>(Class);
};
Msg.bUseMsg_2 = false;
LusMsgBox(Msg.hWnd, Msg, hInst, 175);
};
Msg.undoFunc = [](void *Scene){
close_LusMsgProc();
};
Msg.thisClass = hWnd;
LusInputMsgBox(Msg.hWnd, Msg, hInst, 215);
*
*
*/
#pragma comment(lib,"msimg32")
#pragma warning(disable:4244)
#include <iostream>
using namespace std;
#define WM_GETVALUE 0x401
#define wGETMSG (WPARAM)0x001
#define wGETINITFLAG (WPARAM)0x002
#define sideCheck(_min, _val, _max) ( ( ( (_min) <= (_val) ) && ( (_val) < (_max) ) ) ? true : false)
#define ALPHA_SELECT 140
// FontSize Part
#define DEFAULT_FontSize 15
#define TITLE_FontSize 80
#define LARGE_FontSize 25
#define DEFAULT_MSGWIDTH 170
#define DEFAULT_MSGHEIGHT 180
// DrawLine
#define DL_FILL true
#define DL_FRAME false
#define 마스터클래스
#define 문자열
#define 람다
#define 메세지종료 close_LusMsgProc();
#define 선택지추가사용여부
// Color Box
typedef enum LusColor{
AliceBlue = 0xF0F8FF,
AntiqueWhite = 0xFAEBD7,
Aqua = 0x00FFFF,
Aquamarine = 0x7FFFD4,
Azure = 0xF0FFFF,
Beige = 0xF5F5DC,
Bisque = 0xFFE4C4,
Black = 0x000000,
BlanchedAlmond = 0xFFEBCD,
Blue = 0x0000FF,
BlueViolet = 0x8A2BE2,
Brown = 0xA52A2A,
BurlyWood = 0xDEB887,
CadetBlue = 0x5F9EA0,
Chartreuse = 0x7FFF00,
Chocolate = 0xD2691E,
Coral = 0xFF7F50,
CornflowerBlue = 0x6495ED,
Cornsilk = 0xFFF8DC,
Crimson = 0xDC143C,
Cyan = 0x00FFFF,
DarkBlue = 0x00008B,
DarkCyan = 0x008B8B,
DarkGoldenrod = 0xB8860B,
DarkGray = 0xA9A9A9,
DarkGreen = 0x006400,
DarkKhaki = 0xBDB76B,
DarkMagenta = 0x8B008B,
DarkOliveGreen = 0x556B2F,
DarkOrange = 0xFF8C00,
DarkOrchid = 0x9932CC,
DarkRed = 0x8B0000,
DarkSalmon = 0xE9967A,
DarkSeaGreen = 0x8FBC8F,
DarkSlateBlue = 0x483D8B,
DarkSlateGray = 0x2F4F4F,
DarkTurquoise = 0x00CED1,
DarkViolet = 0x9400D3,
DeepPink = 0xFF1493,
DeepSkyBlue = 0x00BFFF,
DimGray = 0x696969,
DodgerBlue = 0x1E90FF,
Firebrick = 0xB22222,
FloralWhite = 0xFFFAF0,
ForestGreen = 0x228B22,
Fuchsia = 0xFF00FF,
Gainsboro = 0xDCDCDC,
GhostWhite = 0xF8F8FF,
Gold = 0xFFD700,
Goldenrod = 0xDAA520,
Gray = 0x808080,
Green = 0x008000,
GreenYellow = 0xADFF2F,
Honeydew = 0xF0FFF0,
HotPink = 0xFF69B4,
IndianRed = 0xCD5C5C,
Indigo = 0x4B0082,
Ivory = 0xFFFFF0,
Khaki = 0xF0E68C,
Lavender = 0xE6E6FA,
LavenderBlush = 0xFFF0F5,
LawnGreen = 0x7CFC00,
LemonChiffon = 0xFFFACD,
LightBlue = 0xADD8E6,
LightCoral = 0xF08080,
LightCyan = 0xE0FFFF,
LightGoldenrodYellow = 0xFAFAD2,
LightGreen = 0x90EE90,
LightGray = 0xD3D3D3,
LightPink = 0xFFB6C1,
LightSalmon = 0xFFA07A,
LightSeaGreen = 0x20B2AA,
LightSkyBlue = 0x87CEFA,
LightSlateGray = 0x778899,
LightSteelBlue = 0xB0C4DE,
LightYellow = 0xFFFFE0,
Lime = 0x00FF00,
LimeGreen = 0x32CD32,
Linen = 0xFAF0E6,
Magenta = 0xFF00FF,
Maroon = 0x800000,
MediumAquamarine = 0x66CDAA,
MediumBlue = 0x0000CD,
MediumOrchid = 0xBA55D3,
MediumPurple = 0x9370DB,
MediumSeaGreen = 0x3CB371,
MediumSlateBlue = 0x7B68EE,
MediumSpringGreen = 0x00FA9A,
MediumTurquoise = 0x48D1CC,
MediumVioletRed = 0xC71585,
MidnightBlue = 0x191970,
MintCream = 0xF5FFFA,
MistyRose = 0xFFE4E1,
Moccasin = 0xFFE4B5,
NavajoWhite = 0xFFDEAD,
Navy = 0x000080,
OldLace = 0xFDF5E6,
Olive = 0x808000,
OliveDrab = 0x6B8E23,
Orange = 0xFFA500,
OrangeRed = 0xFF4500,
Orchid = 0xDA70D6,
PaleGoldenrod = 0xEEE8AA,
PaleGreen = 0x98FB98,
PaleTurquoise = 0xAFEEEE,
PaleVioletRed = 0xDB7093,
PapayaWhip = 0xFFEFD5,
PeachPuff = 0xFFDAB9,
Peru = 0xCD853F,
Pink = 0xFFC0CB,
Plum = 0xDDA0DD,
PowderBlue = 0xB0E0E6,
Purple = 0x800080,
Red = 0xFF0000,
RosyBrown = 0xBC8F8F,
RoyalBlue = 0x4169E1,
SaddleBrown = 0x8B4513,
Salmon = 0xFA8072,
SandyBrown = 0xF4A460,
SeaGreen = 0x2E8B57,
SeaShell = 0xFFF5EE,
Sienna = 0xA0522D,
Silver = 0xC0C0C0,
SkyBlue = 0x87CEEB,
SlateBlue = 0x6A5ACD,
SlateGray = 0x708090,
Snow = 0xFFFAFA,
SpringGreen = 0x00FF7F,
SteelBlue = 0x4682B4,
Tan = 0xD2B48C,
Teal = 0x008080,
Thistle = 0xD8BFD8,
Tomato = 0xFF6347,
Turquoise = 0x40E0D0,
Violet = 0xEE82EE,
Wheat = 0xF5DEB3,
White = 0xFFFFFF,
WhiteSmoke = 0xF5F5F5,
Yellow = 0xFFFF00,
YellowGreen = 0x9ACD32,
MurkyGray = 0x5F5F5F,
};
struct tag_LusMsg
{
//[필수] hWnd : 현재 윈도우 핸들
HWND hWnd;
//[필수] MsgStartPos : 메세지박스의 "중심" 위치입니다.
POINT MsgStartPos;
//[선택] MsgSize : 메세지박스의 크기입니다.
//         내용이 많을 경우 자동 조정됩니다.
//         생략해도 정상적으로 메세지박스가 생성됩니다.
RECT MsgSize;
//[필수] Title : 메세지박스의 캡션 바에 표시될 문장입니다.
TCHAR *Title;
//[필수] Msg : 메세지박스의 내용입니다.
TCHAR *Msg;
//[필수] InBoxMsg_1 : 메세지박스의 첫번째 선택지입니다.필수입니다.
TCHAR *InBoxMsg_1;
//[선택] InBoxMsg_2 : 메세지박스의 두번째 선택지입니다. 만약 선택지를 하나만 쓰면 생략해도 됩니다.
TCHAR *InBoxMsg_2;
//[선택] bUseMsg_2 : 두번째 선택지를 사용할지를 결정합니다. 기본은 쓰지 않습니다.
bool bUseMsg_2;
//[선택] TextColor : 표시될 텍스트 구문의 색상입니다.기본은 흰색입니다.
COLORREF TextColor;
//[선택] MsgColor : 표시될 텍스트 구문의 색상입니다. 기본은 흰색입니다.
COLORREF MsgColor;
//[선택] FontSize : 폰트 사이즈입니다.생략이 가능합니다.
int FontSize;
//[선택] thisClass : 메세지박스가 호출된 값을 반환받는 "클래스"입니다.
void *thisClass;
//[필수] Msg_1_Func : 첫번째 선택지를 누를 때 호출되는 함수입니다.
void (*Msg_1_Func)(void *Class);
//[선택] Msg_2_Func : 두번째 선택지를 누를 때 호출되는 함수입니다.
void (*Msg_2_Func)(void *Class);
tag_LusMsg() {
hWnd = NULL;
MsgSize = { 0, 0, DEFAULT_MSGWIDTH, DEFAULT_MSGHEIGHT };
bUseMsg_2 = false;
MsgStartPos = { 0, 0 };
FontSize = -1;
thisClass = NULL;
MsgColor = LusColor::MurkyGray;
TextColor = LusColor::White;
}
};
struct tag_LusInputMsg
{
//[필수] hWnd : 현재 윈도우 핸들
HWND hWnd;
//[필수] MsgStartPos : 메세지박스의 "중심" 위치입니다.
POINT MsgStartPos;
//[선택] MsgSize : 메세지박스의 크기입니다.
//내용이 많을 경우 자동 조정됩니다.
//생략해도 정상적으로 메세지박스가 생성됩니다.
RECT MsgSize;
//[필수] Title : 메세지박스의 캡션 바에 표시될 문장입니다.
TCHAR *Title;
//[필수] Msg : 메세지박스의 내용입니다.
TCHAR *Msg;
//[선택] YesBox : 값 입력을 승인하는 선택지입니다.기본은 "확인"입니다.
TCHAR *YesBox;
//[선택] NoBox : 값 입력을 취소하는 선택지입니다.기본은 "취소"입니다.
TCHAR *NoBox;
//[필수] BoxValue : 입력받은 값을 저장하는 문자열입니다.
TCHAR BoxValue[256];
//[선택] TextColor : 표시될 텍스트 구문의 색상입니다.기본은 흰색입니다.
COLORREF TextColor;
//[선택] MsgColor : 표시될 텍스트 구문의 색상입니다.기본은 흰색입니다.
COLORREF MsgColor;
//[선택] FontSize : 폰트 사이즈입니다.생략이 가능합니다.
int FontSize;
//[필수] InputSize : 값 입력 박스의 너비입니다.
int InputSize;
//[필수] InputMax : 입력받는 값의 최대 개수입니다.
//"LusInputMsg"는 InputMax가 12 이상이어야 입력할 수 있습니다.
int InputMax;
//[선택] IsOnlyUseNum : 숫자만 입력할 수 있는지를 체크합니다. 기본은 문자도 입력가능(false)입니다.
bool IsOnlyUseNum;
//[선택] thisClass : 메세지박스가 호출된 값을 반환받는 "클래스"입니다.
void *thisClass;
//[필수] resultFunc : 값을 입력했을 때 호출되는 함수입니다.
void (*resultFunc)(void *Class, TCHAR *output);
//[필수] undoFunc : 취소했을 때 호출되는 함수입니다.
void (*undoFunc)(void *Class);
tag_LusInputMsg(){
hWnd = NULL;
MsgSize = { 0, 0, DEFAULT_MSGWIDTH, DEFAULT_MSGHEIGHT };
MsgStartPos = { 0, 0 };
FontSize = -1;
thisClass = NULL;
IsOnlyUseNum = false;
YesBox = L"확인";
NoBox = L"취소";
BoxValue[0] = '\0';
InputMax = 256;
MsgColor = LusColor::MurkyGray;
TextColor = LusColor::White;
}
};
/*
* 메세지박스의 속성을 설정할 수 있습니다.
* [필수] hWnd : 현재 윈도우 핸들
* [필수] MsgStartPos : 메세지박스의 "중심" 위치입니다.
* [선택] MsgSize : 메세지박스의 크기입니다.
         내용이 많을 경우 자동 조정됩니다.
         생략해도 정상적으로 메세지박스가 생성됩니다.
* [필수] Title : 메세지박스의 캡션 바에 표시될 문장입니다.
* [필수] Msg : 메세지박스의 내용입니다.
* [필수] InBoxMsg_1 : 메세지박스의 첫번째 선택지입니다. 필수입니다.
* [선택] InBoxMsg_2 : 메세지박스의 두번째 선택지입니다.
           만약 선택지를 하나만 쓰면 생략해도 됩니다.
* [선택] bUseMsg_2 : 두번째 선택지를 사용할지를 결정합니다. 기본은 쓰지 않습니다.
* [선택] TextColor : 표시될 텍스트 구문의 색상입니다. 기본은 흰색입니다.
* [선택] MsgColor : 표시될 텍스트 구문의 색상입니다. 기본은 흰색입니다.
* [선택] FontSize : 폰트 사이즈입니다. 생략이 가능합니다.
* [선택] thisClass : 메세지박스가 호출된 값을 반환받는 "클래스"입니다.
* [필수] Msg_1_Func : 첫번째 선택지를 누를 때 호출되는 함수입니다.
* [선택] Msg_2_Func : 두번째 선택지를 누를 때 호출되는 함수입니다.
*/
typedef tag_LusMsg LusMsg;
/*
* 메세지박스를 생성하는 함수입니다.
* LusMsgProc와 LusInputMsgBox는는 프로그램 당 한 번에 하나만 생성시킬 수 있으며
* MessageBox와 다른 로직으로 동작합니다.
* 하지만 MessageBox처럼 이 메세지를 무시할 수 없습니다.
* hWnd : 현재 윈도우 핸들
* Msg : 설정한 메세지박스 속성
* g_hInst : 현재 프로그램의 인스턴스 핸들
* alpha_message : 메세지박스의 투명도입니다. 0 ~ 255 사이의 값.
*/
void LusMsgBox(HWND hWnd, LusMsg Msg, HINSTANCE g_hInst, int alpha_message);
/*
* 메세지박스의 속성을 설정할 수 있습니다.
* [필수] hWnd : 현재 윈도우 핸들
* [필수] MsgStartPos : 메세지박스의 "중심" 위치입니다.
* [선택] MsgSize : 메세지박스의 크기입니다.
         내용이 많을 경우 자동 조정됩니다.
         생략해도 정상적으로 메세지박스가 생성됩니다.
* [필수] Title : 메세지박스의 캡션 바에 표시될 문장입니다.
* [필수] Msg : 메세지박스의 내용입니다.
* [선택] YesBox : 값 입력을 승인하는 선택지입니다. 기본은 "확인"입니다.
* [선택] NoBox : 값 입력을 취소하는 선택지입니다. 기본은 "취소"입니다.
* [필수] BoxValue : 입력받은 값을 저장하는 문자열입니다.
* [선택] TextColor : 표시될 텍스트 구문의 색상입니다. 기본은 흰색입니다.
* [선택] MsgColor : 표시될 텍스트 구문의 색상입니다. 기본은 흰색입니다.
* [선택] FontSize : 폰트 사이즈입니다. 생략이 가능합니다.
* [필수] InputSize : 값 입력 박스의 너비입니다.
* [필수] InputMax : 입력받는 값의 최대 개수입니다.
         "LusInputMsg"는 InputMax가 12 이상이어야 입력할 수 있습니다.
* [선택] IsOnlyUseNum : 숫자만 입력할 수 있는지를 체크합니다. 기본은 문자도 입력가능(false)입니다.
* [선택] thisClass : 메세지박스가 호출된 값을 반환받는 "클래스"입니다.
* [필수] resultFunc : 값을 입력했을 때 호출되는 함수입니다.
* [필수] undoFunc : 취소했을 때 호출되는 함수입니다.
*/
typedef tag_LusInputMsg LusInputMsg;
/*
* 값을 넣을 수 있는 메세지박스를 생성하는 함수입니다.
* LusMsgProc와 LusInputMsgBox는 프로그램 당 한 번에 하나만 생성시킬 수 있습니다.
* MessageBox처럼 이 메세지를 무시할 수 없습니다.
* hWnd : 현재 윈도우 핸들
* Msg : 설정한 메세지박스 속성
* g_hInst : 현재 프로그램의 인스턴스 핸들
* alpha_message : 메세지박스의 투명도입니다. 0 ~ 255 사이의 값.
*/
void LusInputMsgBox(HWND hWnd, LusInputMsg Msg, HINSTANCE g_hInst, int alpha_message);
inline POINT MakePoint(LONG x, LONG y) { POINT pt; pt.x = x; pt.y = y; return pt; }
inline RECT MakeRect(LONG left, LONG top, LONG right, LONG bottom) { RECT rc; SetRect(&rc, left, top, right, bottom); return rc; }
inline RECT MakeRect(POINT left_top, POINT right_bottom) { RECT rc; SetRect(&rc, left_top.x, left_top.y, right_bottom.x, right_bottom.y); return rc; }
inline RECT MakeRect(POINT center, LONG Width, LONG Height) { RECT rc; SetRect(&rc, center.x - Width, center.y - Height, center.x + Width, center.y + Height); return rc; }
template<typename Pt = D2D_POINT_2F> inline POINT MakePoint(Pt pt){ POINT rpt; rpt.x = pt.x; rpt.y = pt.y; return rpt; }
template<typename Rect = D2D_RECT_F> inline POINT MakeRect(Rect rc){ RECT rrc; SetRect(&rrc, rc.left, rc.top, rc.right, rc.bottom); return rrc; }
inline POINT operator+(POINT a, const POINT b) { return MakePoint(a.x + b.x, a.y + b.y); }
inline POINT operator-(POINT a, const POINT b) { return MakePoint(a.x - b.x, a.y - b.y); }
inline POINT operator*(float b, POINT a) { return MakePoint(a.x * b, a.y * b); }
inline bool operator==(POINT p1, POINT p2) { return (p1.x == p2.x && p1.y == p2.y) ? true : false; }
inline bool operator!=(POINT p1, POINT p2) { return (p1.x == p2.x && p1.y == p2.y) ? false : true; }
inline RECT operator+(RECT rc, POINT pt) { return MakeRect(pt.x + rc.left, pt.y + rc.top, pt.x + rc.right, pt.y + rc.bottom); }
inline RECT operator+(POINT pt, RECT rc) { return MakeRect(pt.x + rc.left, pt.y + rc.top, pt.x + rc.right, pt.y + rc.bottom); }
inline RECT operator+(RECT rc_1, RECT rc_2) { return MakeRect(rc_1.left + rc_2.left, rc_1.top + rc_2.top, rc_1.right + rc_2.right, rc_1.bottom + rc_2.bottom); }
inline RECT operator-(POINT pt, RECT rc) { SetRect(&rc, -rc.left, -rc.top, -rc.right, -rc.bottom); return (rc + pt); }
inline RECT operator-(RECT rc, POINT pt) { pt.x = -pt.x; pt.y = -pt.y; return (rc + pt); }
inline RECT operator-(RECT rc_1, RECT rc_2) { return MakeRect(rc_1.left - rc_2.left, rc_1.top - rc_2.top, rc_1.right - rc_2.right, rc_1.bottom - rc_2.bottom); }
inline POINT GetCenterPos(HWND hWnd){ RECT rc; GetClientRect(hWnd, &rc); return MakePoint((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2); }
void close_LusMsgProc();
void DrawLineBox(HDC mainDC, RECT rc, COLORREF main_RGB, COLORREF Line_RGB, int LineLen, bool Type);
void FixValue(LPWSTR DestMsg, int fixnum);
// template function List
template<typename Val> inline
Val sideStore(Val min, Val value, Val max)
{
Val return_val = value;
if (min > value) return_val = min;
if (value > max) return_val = max;
return return_val;
}
template<typename Val> inline
Val pow(Val under, unsigned int power = 2) { Val rVal = 1; while (power > 0) rVal *= under; return rVal; }
template<typename Rect = RECT, typename Len = int> inline
Rect SizeDown(Rect rc, Len len)
{
len = min(rc.right / 2, len);
rc.left += len;
rc.top += len;
rc.right -= len;
rc.bottom -= len;
return rc;
}
template <typename Val, typename Pt> inline
Val Length(Pt StartPoint, Pt EndPoint){ return sqrt(pow(StartPoint.x - EndPoint.x) + pow(StartPoint.y - EndPoint.y)); }
/*
* 메세지박스를 출력하는 함수입니다.
* 메세지박스의 타이틀, 본문, 선택지 1과 2를 출력할 수 있습니다.
* 선택지를 누름에 따른 함수를 작성할 수 있습니다.
* 해당 클래스는 유니코드 문자 집합에서 사용할 수 있습니다.
*/
class CLusMsg{
protected:
LusMsg m_LusMsg;
HINSTANCE m_hInst;
wstring m_strTitle;
wstring m_strMsg;
void *thisClass;
int m_iAlphaLevel;
private:
wstring m_strBt1;
wstring m_strBt2;
bool m_bUseBt2;
int m_iFontSize;
public: // value
void *m_MasterClass;
public: // function
void Initialize(HWND hWnd, HINSTANCE hInst)
{
m_LusMsg.hWnd = hWnd;
m_hInst = hInst;
m_MasterClass = nullptr;
}
/*
메세지를 생성하는 함수입니다.
wstr
*/
void CreateMessageBox(void * masterClass, wstring wstrTitle, wstring wstrMsg,
wstring wstrBt1, void(*Func1)(void *Class),
bool bUseBt2 = false,
wstring wstrBt2 = wstring(), void(*Func2)(void *Class) = nullptr,
int FontSize = DEFAULT_FontSize, int nAlpha = ALPHA_SELECT,
COLORREF TextColor = LusColor::White, COLORREF MsgBkColor = LusColor::Gray,
POINT ptStart = MakePoint(-1, -1), RECT rcSize = MakeRect(0, 0, 0, 0))
{
close_LusMsgProc();
m_MasterClass = masterClass;
// 기본적으로 가운데로 잡습니다. 추후 수정됩니다.
if (ptStart == MakePoint(-1, -1))
{
RECT rcDesktop;
GetWindowRect(m_LusMsg.hWnd, &rcDesktop);
m_LusMsg.MsgStartPos = MakePoint(
(rcDesktop.right - rcDesktop.left) * 0.5,
(rcDesktop.bottom - rcDesktop.top) * 0.5);
}
else
m_LusMsg.MsgStartPos = ptStart;
m_LusMsg.MsgSize = rcSize;
m_LusMsg.FontSize = FontSize;
m_LusMsg.bUseMsg_2 = bUseBt2;
m_strTitle = wstrTitle;
m_strMsg = wstrMsg;
m_strBt1 = wstrBt1;
m_LusMsg.Title = (LPWSTR)m_strTitle.c_str();
m_LusMsg.Msg = (LPWSTR)m_strMsg.c_str();
m_LusMsg.InBoxMsg_1 = (LPWSTR)m_strBt1.c_str();
if (m_LusMsg.bUseMsg_2)
{
m_strBt2 = wstrBt2;
m_LusMsg.InBoxMsg_2 = (LPWSTR)m_strBt2.c_str();
}
m_LusMsg.Msg_1_Func = Func1;
m_LusMsg.Msg_2_Func = Func2;
m_LusMsg.thisClass = m_MasterClass;
LusMsgBox(m_LusMsg.hWnd, m_LusMsg, m_hInst, nAlpha);
}
};
@LusainKim
Copy link
Author

LusDef는 Windows API를 사용하기 조금 더 편하게 만들고, 메세지박스와 입력상자를 커스터마이징할 수 있도록 구현했습니다. POINT와 RECT에 대한 연산자 오버로딩이 정의되어있습니다.

MakePoint와 MakeRect함수를 통하여 원하는 인자값을 가지고 쉽고 편하게 POINT와 RECT형 변수를 만들 수 있습니다.

LusDef는 다음과 같은 기능이 존재합니다.

LusMsg : 루사인이 만든 자작 MessageBox를 출력합니다. 사용법은 LusDef.h에 기술되어있습니다.
LusInputMsg : 루사인이 만든 자작 InputBox를 출력합니다. 사용법은 LusDef.h에 기술되어있습니다.
CLusMsg : LusMsg 구조체를 객체화시켰습니다. LusMsg보다 사용이 간단해졌으며, 추가적인 옵션을 붙일 수 있도록 설계되었습니다.

추가적인 함수입니다.

GetCenterPos : 윈도우 핸들(HWND)를 인자로 받으면 해당 윈도우 클라이언트의 가운데 위치를 반환합니다. 데스크탑의 원점으로부터의 거리이므로, 내부적으로 사용하기 위해서는 추가적인 연산이 필요할 것입니다.

DrawLineBox : 내부에 띠가 쳐진 사각형 박스를 그립니다.
FixValue : 숫자를 금융표기(세자리당 , 표시)로 바꿔줍니다. 인자로 받은 문자열에 결과값을 복사합니다.

sideStore : min과 max 사이로 val을 고정한 값을 반환합니다. val이 min과 max 사이의 값이면 val을 반환합니다.
sideCheck : min과 max 사이에 val이 위치했는지를 체크하여 true와 false를 반환합니다.

pow : n제곱을 반환합니다. 기본적으로 2제곱수를 반환합니다.

SizeDown : 인자로 주어진 Rect의 left, top, right, bottom을 원하는 길이만큼 축소시킨 RECT 변수를 반환합니다.

Length : POINT형 변수 A와 B 사이의 거리를 반환합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment