Finish launcher
This commit is contained in:
parent
a8a609907d
commit
510e02604b
75
src/launcher/image.cpp
Normal file
75
src/launcher/image.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include <std_include.hpp>
|
||||
#include "image.hpp"
|
||||
|
||||
image::image(const size_t resource)
|
||||
{
|
||||
this->bitmap_ = LoadBitmapA(GetModuleHandleA(nullptr), MAKEINTRESOURCEA(resource));
|
||||
}
|
||||
|
||||
image::~image()
|
||||
{
|
||||
DeleteBitmap(this->bitmap_);
|
||||
}
|
||||
|
||||
void image::set_position(const POINT& position)
|
||||
{
|
||||
this->position_ = position;
|
||||
}
|
||||
|
||||
void image::set_size(const POINT& size)
|
||||
{
|
||||
this->size_ = size;
|
||||
}
|
||||
|
||||
bool image::is_hovered(const POINT& mouse) const
|
||||
{
|
||||
return mouse.x >= this->position_.x && mouse.x < (this->position_.x + this->size_.x)
|
||||
&& mouse.y >= this->position_.y && mouse.y < (this->position_.y + this->size_.y);
|
||||
}
|
||||
|
||||
void image::paint(const HDC hdc, const POINT& mouse) const
|
||||
{
|
||||
BITMAP bitmap;
|
||||
GetObject(this->bitmap_, sizeof(bitmap), &bitmap);
|
||||
|
||||
const auto dc = CreateCompatibleDC(hdc);
|
||||
SelectObject(dc, this->bitmap_);
|
||||
|
||||
const LONG modifier = 1;
|
||||
LONG size_offset = 0;
|
||||
LONG position_offset = 0;
|
||||
if (this->is_hovered(mouse))
|
||||
{
|
||||
size_offset = modifier * 2;
|
||||
position_offset = -modifier;
|
||||
}
|
||||
|
||||
SetStretchBltMode(hdc, HALFTONE);
|
||||
StretchBlt(hdc, this->position_.x + position_offset, this->position_.y + position_offset,
|
||||
this->size_.x + size_offset, this->size_.y + size_offset, dc, 0, 0, bitmap.bmWidth,
|
||||
bitmap.bmHeight, SRCCOPY);
|
||||
|
||||
DeleteDC(dc);
|
||||
}
|
||||
|
||||
void image::set_click_listener(std::function<void()> callback)
|
||||
{
|
||||
this->callback_ = callback;
|
||||
}
|
||||
|
||||
void image::click(const POINT& mouse, const bool down)
|
||||
{
|
||||
if(down)
|
||||
{
|
||||
this->down_handled_ = this->is_hovered(mouse);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this->down_handled_ && this->is_hovered(mouse) && this->callback_)
|
||||
{
|
||||
this->callback_();
|
||||
}
|
||||
|
||||
this->down_handled_ = false;
|
||||
}
|
||||
}
|
27
src/launcher/image.hpp
Normal file
27
src/launcher/image.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
class image final
|
||||
{
|
||||
public:
|
||||
image(size_t resource);
|
||||
~image();
|
||||
|
||||
void set_position(const POINT& position);
|
||||
void set_size(const POINT& size);
|
||||
|
||||
bool is_hovered(const POINT& mouse) const;
|
||||
|
||||
void paint(HDC hdc, const POINT& mouse) const;
|
||||
|
||||
void set_click_listener(std::function<void()> callback);
|
||||
|
||||
void click(const POINT& mouse, bool down);
|
||||
|
||||
private:
|
||||
POINT size_{};
|
||||
POINT position_{};
|
||||
HBITMAP bitmap_;
|
||||
|
||||
bool down_handled_ = false;
|
||||
std::function<void()> callback_;
|
||||
};
|
@ -1,12 +1,109 @@
|
||||
#include <std_include.hpp>
|
||||
#include "launcher.hpp"
|
||||
|
||||
launcher::launcher() : window_("Open-IW5", 300, 400)
|
||||
launcher::launcher() : window_("Open-IW5", 265, 432), image_sp_(IMAGE_SP), image_mp_(IMAGE_MP)
|
||||
{
|
||||
this->image_sp_.set_position({75, 50});
|
||||
this->image_mp_.set_position({75, 252});
|
||||
|
||||
this->image_sp_.set_size({100, 100});
|
||||
this->image_mp_.set_size({100, 100});
|
||||
|
||||
this->image_sp_.set_click_listener(std::bind(&launcher::select_mode, this, mode::SINGLEPLAYER));
|
||||
this->image_mp_.set_click_listener(std::bind(&launcher::select_mode, this, mode::MULTIPLAYER));
|
||||
|
||||
this->window_.set_callback(std::bind(&launcher::handler, this, std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3));
|
||||
}
|
||||
|
||||
void launcher::run() const
|
||||
launcher::mode launcher::run() const
|
||||
{
|
||||
this->window_.run();
|
||||
|
||||
return this->mode_;
|
||||
}
|
||||
|
||||
LRESULT launcher::handler(const UINT message, const WPARAM w_param, const LPARAM l_param)
|
||||
{
|
||||
if (message == WM_PAINT)
|
||||
{
|
||||
this->paint();
|
||||
}
|
||||
else if (message == WM_MOUSEMOVE)
|
||||
{
|
||||
this->mouse_move(l_param);
|
||||
}
|
||||
else if (message == WM_LBUTTONDOWN)
|
||||
{
|
||||
this->image_sp_.click(this->mouse_, true);
|
||||
this->image_mp_.click(this->mouse_, true);
|
||||
}
|
||||
else if (message == WM_LBUTTONUP)
|
||||
{
|
||||
this->image_sp_.click(this->mouse_, false);
|
||||
this->image_mp_.click(this->mouse_, false);
|
||||
}
|
||||
else if (message == WM_ERASEBKGND)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProc(this->window_, message, w_param, l_param);
|
||||
}
|
||||
|
||||
void launcher::select_mode(const mode mode)
|
||||
{
|
||||
this->mode_ = mode;
|
||||
this->window_.close();
|
||||
}
|
||||
|
||||
void launcher::draw_text(const HDC hdc)
|
||||
{
|
||||
Gdiplus::Graphics graphics(hdc);
|
||||
Gdiplus::SolidBrush color(Gdiplus::Color(255, 150, 150, 150));
|
||||
Gdiplus::FontFamily font_family(L"Segoe UI");
|
||||
Gdiplus::Font font(&font_family, 18, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);
|
||||
|
||||
graphics.DrawString(L"Singleplayer", -1, &font, {75, 20}, &color);
|
||||
graphics.DrawString(L"Multiplayer", -1, &font, {75, 222}, &color);
|
||||
|
||||
Gdiplus::Pen pen(Gdiplus::Color(50, 255, 255, 255), 2);
|
||||
graphics.DrawLine(&pen, 0, 200, 500, 200);
|
||||
}
|
||||
|
||||
void launcher::paint() const
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(this->window_, &rect);
|
||||
const int width = rect.right - rect.left;
|
||||
const int height = rect.bottom + rect.left;
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
const auto hdc = BeginPaint(this->window_, &ps);
|
||||
|
||||
const auto hdc_copy = CreateCompatibleDC(hdc);
|
||||
const auto bitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||
SelectObject(hdc_copy, bitmap);
|
||||
|
||||
this->window_.clear(hdc_copy);
|
||||
|
||||
this->draw_text(hdc_copy);
|
||||
|
||||
this->image_sp_.paint(hdc_copy, this->mouse_);
|
||||
this->image_mp_.paint(hdc_copy, this->mouse_);
|
||||
|
||||
BitBlt(hdc, 0, 0, width, height, hdc_copy, 0, 0, SRCCOPY);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteDC(hdc_copy);
|
||||
|
||||
EndPaint(this->window_, &ps);
|
||||
}
|
||||
|
||||
void launcher::mouse_move(LPARAM l_param)
|
||||
{
|
||||
this->mouse_.x = GET_X_LPARAM(l_param);
|
||||
this->mouse_.y = GET_Y_LPARAM(l_param);
|
||||
|
||||
InvalidateRect(this->window_, nullptr, FALSE);
|
||||
}
|
||||
|
@ -1,13 +1,36 @@
|
||||
#pragma once
|
||||
#include "window.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
class launcher
|
||||
class launcher final
|
||||
{
|
||||
public:
|
||||
enum mode
|
||||
{
|
||||
NONE,
|
||||
SINGLEPLAYER,
|
||||
MULTIPLAYER,
|
||||
};
|
||||
|
||||
launcher();
|
||||
|
||||
void run() const;
|
||||
mode run() const;
|
||||
|
||||
private:
|
||||
mode mode_ = NONE;
|
||||
|
||||
window window_;
|
||||
|
||||
image image_sp_;
|
||||
image image_mp_;
|
||||
|
||||
POINT mouse_{};
|
||||
|
||||
LRESULT handler(const UINT message, const WPARAM w_param, const LPARAM l_param);
|
||||
|
||||
void select_mode(mode mode);
|
||||
|
||||
static void draw_text(const HDC hdc);
|
||||
void paint() const;
|
||||
void mouse_move(LPARAM l_param);
|
||||
};
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include <std_include.hpp>
|
||||
#include "window.hpp"
|
||||
|
||||
window::window(const std::string& title, int width, int height)
|
||||
window::window(const std::string& title, const int width, const int height)
|
||||
{
|
||||
Gdiplus::GdiplusStartupInput input;
|
||||
GdiplusStartup(&this->token_, &input, nullptr);
|
||||
|
||||
const auto handle = GetModuleHandle(nullptr);
|
||||
|
||||
ZeroMemory(&this->wc_, sizeof(this->wc_));
|
||||
@ -14,14 +17,15 @@ window::window(const std::string& title, int width, int height)
|
||||
this->wc_.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
this->wc_.hIcon = LoadIcon(handle, MAKEINTRESOURCE(102));
|
||||
this->wc_.hIconSm = this->wc_.hIcon;
|
||||
this->wc_.hbrBackground = CreateSolidBrush(RGB(35, 35, 35));//HBRUSH(COLOR_WINDOW);
|
||||
this->wc_.hbrBackground = CreateSolidBrush(RGB(35, 35, 35)); //HBRUSH(COLOR_WINDOW);
|
||||
this->wc_.lpszClassName = L"omw3_window";
|
||||
RegisterClassEx(&this->wc_);
|
||||
|
||||
const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
|
||||
const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
|
||||
|
||||
this->handle_ = CreateWindowExA(NULL, "omw3_window", title.data(), (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width,
|
||||
this->handle_ = CreateWindowExA(NULL, "omw3_window", title.data(),
|
||||
(WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width,
|
||||
height, nullptr, nullptr, handle, nullptr);
|
||||
|
||||
SetWindowLongPtrA(*this, GWLP_USERDATA, LONG_PTR(this));
|
||||
@ -32,6 +36,8 @@ window::~window()
|
||||
this->close();
|
||||
UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance);
|
||||
DeleteObject(this->wc_.hbrBackground);
|
||||
|
||||
Gdiplus::GdiplusShutdown(this->token_);
|
||||
}
|
||||
|
||||
void window::close()
|
||||
@ -59,7 +65,19 @@ void window::run() const
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK window::processor(UINT message, WPARAM w_param, LPARAM l_param) const
|
||||
void window::clear(const HDC hdc) const
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(*this, &rc);
|
||||
FillRect(hdc, &rc, this->wc_.hbrBackground);
|
||||
}
|
||||
|
||||
void window::set_callback(const std::function<LRESULT(UINT, WPARAM, LPARAM)>& callback)
|
||||
{
|
||||
this->callback_ = callback;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param) const
|
||||
{
|
||||
if (message == WM_KILL_WINDOW)
|
||||
{
|
||||
@ -67,13 +85,19 @@ LRESULT CALLBACK window::processor(UINT message, WPARAM w_param, LPARAM l_param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->callback_)
|
||||
{
|
||||
return this->callback_(message, w_param, l_param);
|
||||
}
|
||||
|
||||
return DefWindowProc(*this, message, w_param, l_param);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK window::static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param)
|
||||
{
|
||||
window* self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
const auto self = reinterpret_cast<window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
if (self) return self->processor(message, w_param, l_param);
|
||||
|
||||
return DefWindowProc(hwnd, message, w_param, l_param);
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,17 @@ public:
|
||||
void close();
|
||||
void run() const;
|
||||
|
||||
void clear(const HDC hdc) const;
|
||||
|
||||
void set_callback(const std::function<LRESULT(UINT, WPARAM, LPARAM)>& callback);
|
||||
|
||||
operator HWND() const;
|
||||
|
||||
private:
|
||||
ULONG_PTR token_;
|
||||
WNDCLASSEX wc_{};
|
||||
HWND handle_ = nullptr;
|
||||
std::function<LRESULT(UINT, WPARAM, LPARAM)> callback_;
|
||||
|
||||
LRESULT CALLBACK processor(UINT message, WPARAM w_param, LPARAM l_param) const;
|
||||
static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -4,5 +4,20 @@
|
||||
int CALLBACK WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)
|
||||
{
|
||||
launcher launcher;
|
||||
launcher.run();
|
||||
const auto mode = launcher.run();
|
||||
|
||||
if(mode == launcher::mode::NONE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(mode == launcher::mode::SINGLEPLAYER)
|
||||
{
|
||||
OutputDebugStringA("\n\nSINGLEPLAYER\n\n");
|
||||
}
|
||||
else if(mode == launcher::mode::MULTIPLAYER)
|
||||
{
|
||||
OutputDebugStringA("\n\nMULTIPLAYER\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
4
src/resource.hpp
Normal file
4
src/resource.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define IMAGE_SP 300
|
||||
#define IMAGE_MP 301
|
@ -8,6 +8,7 @@
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "windows.h"
|
||||
#include "resource.hpp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
@ -80,6 +81,15 @@ BEGIN
|
||||
END
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Binary Data
|
||||
//
|
||||
|
||||
IMAGE_SP BITMAP "resources/singleplayer.bmp"
|
||||
IMAGE_MP BITMAP "resources/multiplayer.bmp"
|
||||
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
BIN
src/resources/multiplayer.bmp
Normal file
BIN
src/resources/multiplayer.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
BIN
src/resources/singleplayer.bmp
Normal file
BIN
src/resources/singleplayer.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
@ -1,16 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4458)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <Windowsx.h>
|
||||
#include <objidl.h>
|
||||
#include <gdiplus.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
#pragma comment (lib, "gdiplus.lib")
|
||||
|
||||
#pragma warning(disable: 4100)
|
||||
|
||||
#include "resource.hpp"
|
||||
|
||||
#include "steam/steam.hpp"
|
||||
|
Loading…
Reference in New Issue
Block a user