Finish launcher

This commit is contained in:
momo5502 2018-12-23 18:25:22 +01:00
parent a8a609907d
commit 510e02604b
12 changed files with 303 additions and 10 deletions

75
src/launcher/image.cpp Normal file
View 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
View 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_;
};

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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
View File

@ -0,0 +1,4 @@
#pragma once
#define IMAGE_SP 300
#define IMAGE_MP 301

View File

@ -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
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

View File

@ -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"