메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

버튼 스타일

데브카페
Devcafe (토론 | 기여)님의 2026년 5월 15일 (금) 17:53 판 (새 문서: == 플랫 버튼 스타일 == ## 1. BS_FLAT 스타일 (가장 간단) <source lang=autoit> #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> $hGUI = GUICreate("Flat Button", 300, 200) GUISetBkColor(0xFFFFFF) $hBtn = GUICtrlCreateButton("클릭", 50, 50, 200, 40, $BS_FLAT) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd </source> 3D 테두리가 제거되지만, 마우스 오버 시 테두리가 살아나서 완전한 플랫은 아닙니다. ## 2. Lab...)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)

플랫 버튼 스타일

    1. 1. BS_FLAT 스타일 (가장 간단)

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

$hGUI = GUICreate("Flat Button", 300, 200)
GUISetBkColor(0xFFFFFF)

$hBtn = GUICtrlCreateButton("클릭", 50, 50, 200, 40, $BS_FLAT)

GUISetState()
While GUIGetMsg() <> $GUI_EVENT_CLOSE
WEnd


3D 테두리가 제거되지만, 마우스 오버 시 테두리가 살아나서 완전한 플랫은 아닙니다.

    1. 2. Label + 색상 조합 (완전 플랫)

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

$hGUI = GUICreate("Flat Button", 400, 300)
GUISetBkColor(0xFFFFFF)

; 버튼처럼 동작하는 Label
$hBtn1 = _CREATE_FLAT_BUTTON("저장",    30,  50, 150, 45, 0x2196F3, 0xFFFFFF)
$hBtn2 = _CREATE_FLAT_BUTTON("취소",   210,  50, 150, 45, 0xF44336, 0xFFFFFF)
$hBtn3 = _CREATE_FLAT_BUTTON("설정",    30, 120, 150, 45, 0x4CAF50, 0xFFFFFF)
$hBtn4 = _CREATE_FLAT_BUTTON("닫기",   210, 120, 150, 45, 0x757575, 0xFFFFFF)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hBtn1
            MsgBox(0, "", "저장 클릭")
        Case $hBtn2
            MsgBox(0, "", "취소 클릭")
        Case $hBtn3
            MsgBox(0, "", "설정 클릭")
        Case $hBtn4
            MsgBox(0, "", "닫기 클릭")
    EndSwitch
WEnd

Func _CREATE_FLAT_BUTTON($sText, $iX, $iY, $iW, $iH, $iBgColor, $iFontColor)
    Local $hLabel = GUICtrlCreateLabel($sText, $iX, $iY, $iW, $iH, _
            BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor($hLabel, $iBgColor)
    GUICtrlSetColor($hLabel, $iFontColor)
    GUICtrlSetFont($hLabel, 11, 600, 0, "맑은 고딕")
    GUICtrlSetCursor($hLabel, 0)  ; 손가락 커서
    Return $hLabel
EndFunc
    1. 3. GDI+ Owner-Draw (호버 효과 포함)

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <StaticConstants.au3>

Global Const $FLAT_COLOR_NORMAL  = 0xFF2196F3  ; 파란색
Global Const $FLAT_COLOR_HOVER   = 0xFF1976D2  ; 진한 파란색
Global Const $FLAT_COLOR_PRESS   = 0xFF0D47A1  ; 더 진한 파란색
Global Const $FLAT_COLOR_TEXT    = 0xFFFFFFFF  ; 흰색

Global $g_aBtns[0][6]  ; [n][CtrlID, X, Y, W, H, Text]
Global $g_iHoverIdx = -1
Global $g_iPressIdx = -1
Global $g_hGUI

_GDIPlus_Startup()

$g_hGUI = GUICreate("GDI+ Flat Buttons", 400, 300)
GUISetBkColor(0xF5F5F5)

; GDI+ 그리기용 Pic 컨트롤 (전체 영역)
Global $g_hPic = GUICtrlCreatePic("", 0, 0, 400, 300)
GUICtrlSetState($g_hPic, $GUI_DISABLE)

; 버튼 등록
_ADD_FLAT_BUTTON(30,   50, 150, 45, "저장")
_ADD_FLAT_BUTTON(210,  50, 150, 45, "취소")
_ADD_FLAT_BUTTON(30,  120, 150, 45, "설정")
_ADD_FLAT_BUTTON(210, 120, 150, 45, "닫기")

_DRAW_ALL_BUTTONS()

GUISetState()
GUIRegisterMsg($WM_MOUSEMOVE, "_WM_MOUSEMOVE")
GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")
GUIRegisterMsg($WM_LBUTTONUP, "_WM_LBUTTONUP")

While GUIGetMsg() <> $GUI_EVENT_CLOSE
WEnd

_GDIPlus_Shutdown()

; ── 버튼 추가 ──
Func _ADD_FLAT_BUTTON($iX, $iY, $iW, $iH, $sText)
    Local $iIdx = UBound($g_aBtns)
    ReDim $g_aBtns[$iIdx + 1][6]
    $g_aBtns[$iIdx][0] = $iIdx
    $g_aBtns[$iIdx][1] = $iX
    $g_aBtns[$iIdx][2] = $iY
    $g_aBtns[$iIdx][3] = $iW
    $g_aBtns[$iIdx][4] = $iH
    $g_aBtns[$iIdx][5] = $sText
EndFunc

; ── 전체 버튼 그리기 ──
Func _DRAW_ALL_BUTTONS()
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0(400, 300)
    Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4)
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 5)
    _GDIPlus_GraphicsClear($hGfx, 0xFFF5F5F5)

    Local $hFontFamily = _GDIPlus_FontFamilyCreate("맑은 고딕")
    Local $hFont = _GDIPlus_FontCreate($hFontFamily, 12, 1)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)      ; 가로 중앙
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)   ; 세로 중앙

    Local $hTextBrush = _GDIPlus_BrushCreateSolid($FLAT_COLOR_TEXT)

    For $i = 0 To UBound($g_aBtns) - 1
        ; 상태별 색상 결정
        Local $iColor = $FLAT_COLOR_NORMAL
        If $i = $g_iPressIdx Then
            $iColor = $FLAT_COLOR_PRESS
        ElseIf $i = $g_iHoverIdx Then
            $iColor = $FLAT_COLOR_HOVER
        EndIf

        ; 둥근 사각형 배경
        Local $hPath = _GDIPlus_PathCreate()
        Local $r = 8  ; 둥근 반지름
        Local $bX = $g_aBtns[$i][1], $bY = $g_aBtns[$i][2]
        Local $bW = $g_aBtns[$i][3], $bH = $g_aBtns[$i][4]
        _GDIPlus_PathAddArc($hPath, $bX, $bY, $r * 2, $r * 2, 180, 90)
        _GDIPlus_PathAddArc($hPath, $bX + $bW - $r * 2, $bY, $r * 2, $r * 2, 270, 90)
        _GDIPlus_PathAddArc($hPath, $bX + $bW - $r * 2, $bY + $bH - $r * 2, $r * 2, $r * 2, 0, 90)
        _GDIPlus_PathAddArc($hPath, $bX, $bY + $bH - $r * 2, $r * 2, $r * 2, 90, 90)
        _GDIPlus_PathCloseFigure($hPath)

        Local $hBrush = _GDIPlus_BrushCreateSolid($iColor)
        _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_PathDispose($hPath)

        ; 텍스트
        Local $tRect = _GDIPlus_RectFCreate($bX, $bY, $bW, $bH)
        _GDIPlus_GraphicsDrawStringEx($hGfx, $g_aBtns[$i][5], $hFont, $tRect, $hFormat, $hTextBrush)
    Next

    ; Pic에 적용
    Local $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($g_hPic, 0x0172, 0, $hHBmp))  ; STM_SETIMAGE
    _WinAPI_DeleteObject($hHBmp)

    _GDIPlus_BrushDispose($hTextBrush)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFontFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_BitmapDispose($hBitmap)
EndFunc

; ── 마우스 위치로 버튼 인덱스 찾기 ──
Func _HIT_TEST($iMX, $iMY)
    For $i = 0 To UBound($g_aBtns) - 1
        If $iMX >= $g_aBtns[$i][1] And $iMX <= $g_aBtns[$i][1] + $g_aBtns[$i][3] And _
           $iMY >= $g_aBtns[$i][2] And $iMY <= $g_aBtns[$i][2] + $g_aBtns[$i][4] Then
            Return $i
        EndIf
    Next
    Return -1
EndFunc

; ── 마우스 이동 ──
Func _WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    Local $iMX = BitAND($lParam, 0xFFFF)
    Local $iMY = BitShift(BitAND($lParam, 0xFFFF0000), 16)
    Local $iIdx = _HIT_TEST($iMX, $iMY)
    If $iIdx <> $g_iHoverIdx Then
        $g_iHoverIdx = $iIdx
        _DRAW_ALL_BUTTONS()
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

; ── 마우스 누름 ──
Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    Local $iMX = BitAND($lParam, 0xFFFF)
    Local $iMY = BitShift(BitAND($lParam, 0xFFFF0000), 16)
    $g_iPressIdx = _HIT_TEST($iMX, $iMY)
    If $g_iPressIdx >= 0 Then _DRAW_ALL_BUTTONS()
    Return $GUI_RUNDEFMSG
EndFunc

; ── 마우스 뗌 ──
Func _WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam)
    Local $iMX = BitAND($lParam, 0xFFFF)
    Local $iMY = BitShift(BitAND($lParam, 0xFFFF0000), 16)
    Local $iIdx = _HIT_TEST($iMX, $iMY)
    If $iIdx >= 0 And $iIdx = $g_iPressIdx Then
        ; 버튼 클릭 이벤트
        MsgBox(0, "클릭", $g_aBtns[$iIdx][5] & " 버튼 클릭!")
    EndIf
    $g_iPressIdx = -1
    _DRAW_ALL_BUTTONS()
    Return $GUI_RUNDEFMSG
EndFunc


세 방식의 차이를 정리하면 다음과 같습니다.

    • 방법 1 (BS_FLAT)** — 코드 한 줄이면 되지만 Windows 기본 버튼 렌더링에 의존하므로 완전한 플랫이 아닙니다. 마우스 오버 시 3D 테두리가 나타납니다.
    • 방법 2 (Label 활용)** — Label에 배경색과 폰트색을 입히는 방식으로, 코드가 간결하면서도 완전 플랫합니다. 다만 호버/프레스 시 색상 변화를 주려면 타이머나 메시지 처리를 추가해야 합니다.
    • 방법 3 (GDI+ Owner-Draw)** — 가장 자유도가 높습니다. 둥근 모서리, 호버 색상 변화, 프레스 효과까지 완전히 커스텀 가능합니다. 코드량이 많지만 SQL*KEY처럼 UI를 세밀하게 제어해야 하는 프로그램에 적합합니다.

Comments