mirror of
https://github.com/pj64team/Project64-Legacy.git
synced 2026-04-02 20:55:40 +00:00
Updated to About Project64 Legacy - to include a dash gap between Title and current time of Build (Thanks foir adding this Ice)
435 lines
11 KiB
C++
435 lines
11 KiB
C++
#include <windows.h>
|
|
#include <ATLBASE.H>
|
|
#include <EXDISP.h>
|
|
#include <CommCtrl.h>
|
|
#include "main.h"
|
|
#include "resource.h"
|
|
|
|
LRESULT CALLBACK AboutBoxProc (HWND, UINT, WPARAM, LPARAM);
|
|
void AboutCenterImage (HWND hDlg);
|
|
|
|
int ComputeHeight(HFONT font, RECT rect, char* message);
|
|
void DrawBoxText(HDC dc, RECT rect, HFONT font, int location);
|
|
void FillHelper();
|
|
void FreeHelper();
|
|
void ComputeDimensions(HWND hDlg);
|
|
void SetScrollBarSize(HWND hDlg);
|
|
void AdjustRectangle(RECT *rect);
|
|
void DrawBox(HDC dc, RECT rect);
|
|
void DrawTitle(HDC dc, RECT rect);
|
|
|
|
typedef struct {
|
|
int allocated;
|
|
int count;
|
|
char **strings;
|
|
|
|
int *height;
|
|
int *string_height;
|
|
int name_width;
|
|
int desc_width;
|
|
|
|
HFONT title_font;
|
|
HFONT title_font_i;
|
|
HFONT name_font;
|
|
HFONT desc_font;
|
|
} AboutHelper;
|
|
|
|
AboutHelper helper;
|
|
#define left_margin 10
|
|
#define title_padding 10
|
|
#define text_padding 20
|
|
HWND hScroll;
|
|
|
|
void AboutBox (void) {
|
|
DialogBox(hInst, MAKEINTRESOURCE(IDD_About), hMainWindow, (DLGPROC)AboutBoxProc);
|
|
}
|
|
|
|
LRESULT CALLBACK AboutBoxProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|
switch (uMsg) {
|
|
case WM_INITDIALOG:
|
|
{
|
|
HDC hdc = GetDC(NULL);
|
|
int point1 = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
|
int point2 = -MulDiv(14, GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
SetWindowText(hDlg, "About Project64 Legacy - " __DATE__ " " __TIME__);
|
|
|
|
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, "ICON"));
|
|
|
|
CoInitialize(NULL);
|
|
AboutCenterImage(hDlg);
|
|
hScroll = GetDlgItem(hDlg, IDC_ABOUT_SCROLL);
|
|
|
|
if (helper.allocated != 0) { FreeHelper(); }
|
|
|
|
helper.title_font = CreateFont(point2,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Times"));
|
|
|
|
helper.title_font_i = CreateFont(point2,0,0,0,FW_BOLD,TRUE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Times"));
|
|
|
|
helper.name_font = CreateFont(point1,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Times"));
|
|
|
|
helper.desc_font = CreateFont(point1,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Times"));
|
|
|
|
FillHelper();
|
|
ComputeDimensions(hDlg);
|
|
SetScrollBarSize(hDlg);
|
|
|
|
break;
|
|
}
|
|
case WM_VSCROLL:
|
|
{
|
|
int CurPos, NewPos, min, max;
|
|
|
|
GetScrollRange(hScroll, SB_CTL, &min, &max);
|
|
NewPos = CurPos = GetScrollPos(hScroll, SB_CTL);
|
|
|
|
switch (LOWORD(wParam)) {
|
|
case SB_TOP:
|
|
NewPos = 0;
|
|
break;
|
|
|
|
case SB_LINEUP:
|
|
if (CurPos > 0)
|
|
NewPos -= 10;
|
|
break;
|
|
|
|
case SB_THUMBPOSITION:
|
|
NewPos = HIWORD(wParam);
|
|
break;
|
|
|
|
case SB_THUMBTRACK:
|
|
NewPos = HIWORD(wParam);
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
if (CurPos < max)
|
|
NewPos += 10;
|
|
break;
|
|
|
|
case SB_BOTTOM:
|
|
NewPos = max;
|
|
break;
|
|
|
|
case SB_ENDSCROLL:
|
|
break;
|
|
}
|
|
|
|
SetScrollPos(hScroll, SB_CTL, NewPos, TRUE);
|
|
if (NewPos != CurPos)
|
|
InvalidateRect(hDlg, NULL, FALSE);
|
|
break;
|
|
}
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT paint;
|
|
HWND hWnd;
|
|
HDC dc, compatdc;
|
|
HBITMAP compatbm;
|
|
HBRUSH hBrush;
|
|
int i, width;
|
|
RECT rect;
|
|
HFONT font;
|
|
|
|
hWnd = GetDlgItem(hDlg, IDC_ABOUT_VER);
|
|
dc = BeginPaint(hWnd, &paint);
|
|
|
|
GetClientRect(hWnd, &rect);
|
|
compatdc = CreateCompatibleDC(dc);
|
|
compatbm = CreateCompatibleBitmap(dc, rect.right, rect.bottom);
|
|
SelectObject(compatdc, compatbm);
|
|
|
|
// Fill the background with a grayish color
|
|
hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
|
|
FillRect(compatdc, &rect, hBrush);
|
|
SetBkMode(compatdc, TRANSPARENT);
|
|
|
|
// Compute the starting point
|
|
rect.top = title_padding - GetScrollPos(hScroll, SB_CTL);
|
|
rect.left = left_margin;
|
|
|
|
// Draw the title
|
|
DrawTitle(compatdc, rect);
|
|
|
|
// Iterate through each string, start at 1 since the title has been handled.
|
|
for (i = 1; i < helper.count; i++) {
|
|
switch (i % 4) {
|
|
case 1:
|
|
rect.top = (i == 1) ? (rect.top + helper.height[0]) : rect.bottom;
|
|
rect.bottom = rect.top + helper.height[(i / 4) + 1] + text_padding;
|
|
rect.right = left_margin;
|
|
case 3:
|
|
width = helper.name_width;
|
|
font = helper.name_font;
|
|
break;
|
|
case 0:
|
|
case 2:
|
|
width = helper.desc_width;
|
|
font = helper.desc_font;
|
|
break;
|
|
}
|
|
|
|
rect.left = rect.right;
|
|
rect.right += width;
|
|
DrawBoxText(compatdc, rect, font, i);
|
|
}
|
|
|
|
GetClientRect(hWnd, &rect);
|
|
BitBlt(dc, 0, 0, rect.right, rect.bottom, compatdc, 0, 0, SRCCOPY);
|
|
|
|
DeleteObject(hBrush);
|
|
DeleteObject(compatbm);
|
|
DeleteDC(compatdc);
|
|
EndPaint(hWnd, &paint);
|
|
return FALSE;
|
|
}
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
POINT mouse_click = {LOWORD(lParam), HIWORD(lParam)};
|
|
RECT dialog, image;
|
|
|
|
GetClientRect(hDlg, &dialog); // The about window's size
|
|
ClientToScreen(hDlg, (LPPOINT)&dialog); // Offset the top and left to be relative to the screen
|
|
mouse_click.x += dialog.left;
|
|
mouse_click.y += dialog.top;
|
|
|
|
// Disabled URL on Image Click - Gent (13-09.2021)
|
|
|
|
// GetWindowRect(GetDlgItem(hDlg, IDB_PJ64LOGO), &image);
|
|
|
|
// if (PtInRect(&image, mouse_click))
|
|
// ShellExecute(NULL, "open", "http://www.project64-legacy.com", NULL, NULL, SW_SHOWMAXIMIZED);
|
|
|
|
break;
|
|
}
|
|
case WM_MOUSEWHEEL:
|
|
{
|
|
if (GET_WHEEL_DELTA_WPARAM(wParam) > 0)
|
|
SendMessage(hDlg, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0L);
|
|
else
|
|
SendMessage(hDlg, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0L);
|
|
}
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam)) {
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
CoUninitialize();
|
|
EndDialog(hDlg, 0);
|
|
FreeHelper();
|
|
break;
|
|
}
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void FillHelper() {
|
|
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_ABOUT_TXT), "Text");
|
|
LPCSTR string = (LPCSTR)LoadResource(NULL, hRes);
|
|
char *string_copy, *part;
|
|
int length;
|
|
|
|
length = SizeofResource(NULL, hRes);
|
|
|
|
string_copy = (char *)malloc(length + 1);
|
|
strncpy(string_copy, string, length);
|
|
string_copy[length] = '\0';
|
|
|
|
part = strtok(string_copy, "\n\r");
|
|
|
|
while (part != NULL) {
|
|
if (helper.allocated == helper.count) {
|
|
char **junk = (char **)realloc(helper.strings, sizeof(char *) * (helper.allocated + 8));
|
|
|
|
if (junk == NULL) { break; }
|
|
helper.strings = junk;
|
|
helper.allocated += 8;
|
|
}
|
|
|
|
helper.strings[helper.count] = (char *)malloc(strlen(part) + 1);
|
|
|
|
if (helper.strings[helper.count] != NULL) {
|
|
strncpy(helper.strings[helper.count], part, strlen(part));
|
|
helper.strings[helper.count][strlen(part)] = '\0';
|
|
helper.count++;
|
|
}
|
|
|
|
part = strtok(NULL, "\n\r");
|
|
}
|
|
|
|
free(string_copy);
|
|
}
|
|
|
|
void ComputeDimensions(HWND hDlg) {
|
|
int i, index2;
|
|
RECT rect;
|
|
HFONT font;
|
|
|
|
GetClientRect(GetDlgItem(hDlg, IDC_ABOUT_VER), &rect);
|
|
i = (rect.right / 2) - 8;
|
|
helper.name_width = i / 3;
|
|
helper.desc_width = i - helper.name_width;
|
|
|
|
helper.height = (int *)malloc(sizeof(int) * ((helper.count / 4) + 2));
|
|
helper.string_height = (int *)malloc(sizeof(int) * helper.allocated);
|
|
|
|
if (helper.height == NULL || helper.string_height == NULL) { return; }
|
|
|
|
for (i = 0; i <= ((helper.count - 1) / 4) + 1; i++)
|
|
helper.height[i] = 0;
|
|
|
|
helper.height[0] = ComputeHeight(helper.title_font, rect, helper.strings[0]) + title_padding;
|
|
helper.string_height[0] = helper.height[0];
|
|
|
|
for (i = 1; i < helper.count; i++) {
|
|
if (i % 2 == 0) {
|
|
rect.right = helper.desc_width;
|
|
font = helper.desc_font;
|
|
} else {
|
|
rect.right = helper.name_width;
|
|
font = helper.name_font;
|
|
}
|
|
|
|
helper.string_height[i] = ComputeHeight(font, rect, helper.strings[i]);
|
|
index2 = ((i - 1) / 4) + 1;
|
|
|
|
if (helper.height[index2] < helper.string_height[i])
|
|
helper.height[index2] = helper.string_height[i];
|
|
}
|
|
}
|
|
|
|
void SetScrollBarSize(HWND hDlg) {
|
|
int total_height, i;
|
|
SCROLLINFO si;
|
|
RECT rect;
|
|
|
|
if (hScroll == NULL)
|
|
hScroll = GetDlgItem(hDlg, IDC_ABOUT_SCROLL);
|
|
|
|
GetClientRect(GetDlgItem(hDlg, IDC_ABOUT_VER), &rect);
|
|
|
|
total_height = 0;
|
|
for (i = 0; i <= (helper.count / 4) + 1; i++)
|
|
total_height += helper.height[i] + text_padding;
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
si.nMin = 0;
|
|
si.nMax = total_height;
|
|
si.nPage = total_height / 2;
|
|
si.nPos = 0;
|
|
|
|
SetScrollInfo(hScroll, SB_CTL, &si, TRUE);
|
|
}
|
|
|
|
void FreeHelper() {
|
|
int i;
|
|
|
|
for (i = 0; i < helper.count; i++)
|
|
free(helper.strings[i]);
|
|
|
|
free(helper.strings);
|
|
free(helper.height);
|
|
free(helper.string_height);
|
|
helper.strings = NULL;
|
|
helper.height = NULL;
|
|
helper.string_height = NULL;
|
|
DeleteObject(helper.desc_font);
|
|
DeleteObject(helper.name_font);
|
|
DeleteObject(helper.title_font);
|
|
DeleteObject(helper.title_font_i);
|
|
helper.allocated = 0;
|
|
helper.count = 0;
|
|
}
|
|
|
|
void AboutCenterImage(HWND hDlg) {
|
|
RECT rect, rect2;
|
|
int x, y;
|
|
|
|
// rect will hold the size of the entire dialog
|
|
// rect2 holds the size of the pj64 logo
|
|
GetClientRect(hDlg, &rect);
|
|
GetWindowRect(GetDlgItem(hDlg, IDB_PJ64LOGO), &rect2);
|
|
|
|
// Center the image horizontally
|
|
x = (rect.right - rect2.right + rect2.left) / 2;
|
|
|
|
// Keep the old vertical position, no reason to change it
|
|
ScreenToClient(hDlg, (LPPOINT)&rect2);
|
|
y = rect2.top;
|
|
|
|
// Center the image and it's container horizontally, keeping it's vertical position
|
|
SetWindowPos(GetDlgItem(hDlg, IDB_PJ64LOGO), HWND_TOP, x, y, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION);
|
|
}
|
|
|
|
int ComputeHeight(HFONT font, RECT rect, char* message) {
|
|
HDC dc = GetDC(NULL);
|
|
int height = 0;
|
|
|
|
SelectObject(dc, font);
|
|
AdjustRectangle(&rect);
|
|
height = DrawText(dc, message, strlen(message), &rect, DT_WORDBREAK | DT_CALCRECT);
|
|
ReleaseDC(NULL, dc);
|
|
return height;
|
|
}
|
|
|
|
void DrawTitle(HDC dc, RECT rect) {
|
|
int mid_point, full_length;
|
|
char *find;
|
|
|
|
if (dc == NULL) { return; }
|
|
|
|
find = strchr(helper.strings[0], ':');
|
|
full_length = strlen(helper.strings[0]);
|
|
|
|
if (find == NULL) {
|
|
mid_point = full_length;
|
|
SelectObject(dc, helper.title_font);
|
|
} else {
|
|
SelectObject(dc, helper.title_font_i);
|
|
mid_point = (int)(find - helper.strings[0]) + 1;
|
|
}
|
|
|
|
DrawText(dc, helper.strings[0], mid_point, &rect, DT_NOCLIP);
|
|
|
|
if (mid_point < full_length) {
|
|
DrawText(dc, helper.strings[0], mid_point, &rect, DT_NOCLIP | DT_CALCRECT);
|
|
rect.left = rect.right;
|
|
SelectObject(dc, helper.title_font);
|
|
DrawText(dc, helper.strings[0] + mid_point, -1, &rect, DT_NOCLIP);
|
|
}
|
|
}
|
|
|
|
void DrawBoxText(HDC dc, RECT rect, HFONT font, int location) {
|
|
DrawBox(dc, rect);
|
|
|
|
AdjustRectangle(&rect);
|
|
rect.top += (rect.bottom - rect.top - helper.string_height[location]) / 2;
|
|
SelectObject(dc, font);
|
|
DrawText(dc, helper.strings[location], -1, &rect, DT_WORDBREAK);
|
|
}
|
|
|
|
void DrawBox(HDC dc, RECT rect) {
|
|
HBRUSH brush;
|
|
|
|
if (dc == NULL) { return; }
|
|
|
|
brush = CreateSolidBrush(RGB(0,0,0));
|
|
rect.bottom -= 1;
|
|
rect.right -= 1;
|
|
|
|
FrameRect(dc, &rect, brush);
|
|
DeleteObject(brush);
|
|
}
|
|
|
|
void AdjustRectangle(RECT *rect) {
|
|
rect->left += 5;
|
|
rect->right -= 5;
|
|
}
|