Replace standard message boxes with my own, which will word-wrap
consistently across multiple versionf of Windows, and perhaps not be immediately ignored by the user. [git-p4: depot-paths = "//depot/solvespace/": change = 2108]
This commit is contained in:
parent
342729d9a4
commit
aaf0984882
|
@ -176,7 +176,7 @@ void SolveSpace::ExportViewOrWireframeTo(char *filename, bool wireframe) {
|
||||||
out);
|
out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!out->HasCanvasSize()) {
|
if(out && !out->HasCanvasSize()) {
|
||||||
// These file formats don't have a canvas size, so they just
|
// These file formats don't have a canvas size, so they just
|
||||||
// get exported in the raw coordinate system. So indicate what
|
// get exported in the raw coordinate system. So indicate what
|
||||||
// that was on-screen.
|
// that was on-screen.
|
||||||
|
|
|
@ -789,7 +789,8 @@ void SolveSpace::MenuHelp(int id) {
|
||||||
Message("This is SolveSpace version 1.6.\r\n\r\n"
|
Message("This is SolveSpace version 1.6.\r\n\r\n"
|
||||||
"For more information, see http://solvespace.com/\r\n\r\n"
|
"For more information, see http://solvespace.com/\r\n\r\n"
|
||||||
"Built " __TIME__ " " __DATE__ ".\r\n\r\n"
|
"Built " __TIME__ " " __DATE__ ".\r\n\r\n"
|
||||||
"Copyright 2008-2010 Useful Subset, LLC. All Rights Reserved.");
|
"Copyright 2008-2010 Useful Subset, LLC.\r\n"
|
||||||
|
"All Rights Reserved.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_LICENSE: {
|
case GraphicsWindow::MNU_LICENSE: {
|
||||||
|
|
|
@ -152,8 +152,7 @@ void dbp(char *str, ...);
|
||||||
CO((tri).a), CO((tri).b), CO((tri).c))
|
CO((tri).a), CO((tri).b), CO((tri).c))
|
||||||
|
|
||||||
void SetWindowTitle(char *str);
|
void SetWindowTitle(char *str);
|
||||||
void Message(char *str, ...);
|
void DoMessageBox(char *str, int rows, int cols, BOOL error);
|
||||||
void Error(char *str, ...);
|
|
||||||
void SetTimerFor(int milliseconds);
|
void SetTimerFor(int milliseconds);
|
||||||
void ExitNow(void);
|
void ExitNow(void);
|
||||||
|
|
||||||
|
@ -235,6 +234,8 @@ void MakePathRelative(char *base, char *path);
|
||||||
void MakePathAbsolute(char *base, char *path);
|
void MakePathAbsolute(char *base, char *path);
|
||||||
bool StringAllPrintable(char *str);
|
bool StringAllPrintable(char *str);
|
||||||
bool StringEndsIn(char *str, char *ending);
|
bool StringEndsIn(char *str, char *ending);
|
||||||
|
void Message(char *str, ...);
|
||||||
|
void Error(char *str, ...);
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
public:
|
public:
|
||||||
|
|
75
util.cpp
75
util.cpp
|
@ -125,6 +125,81 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
|
||||||
mat[15] = a44;
|
mat[15] = a44;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Word-wrap the string for our message box appropriately, and then display
|
||||||
|
// that string.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void DoStringForMessageBox(char *str, va_list f, bool error)
|
||||||
|
{
|
||||||
|
char inBuf[1024*50];
|
||||||
|
vsprintf(inBuf, str, f);
|
||||||
|
|
||||||
|
char outBuf[1024*50];
|
||||||
|
int i = 0, j = 0, len = 0, longestLen = 47;
|
||||||
|
int rows = 0, cols = 0;
|
||||||
|
|
||||||
|
// Count the width of the longest line that starts with spaces; those
|
||||||
|
// are list items, that should not be split in the middle.
|
||||||
|
bool listLine = false;
|
||||||
|
while(inBuf[i]) {
|
||||||
|
if(inBuf[i] == '\r') {
|
||||||
|
// ignore these
|
||||||
|
} else if(inBuf[i] == ' ' && len == 0) {
|
||||||
|
listLine = true;
|
||||||
|
} else if(inBuf[i] == '\n') {
|
||||||
|
if(listLine) longestLen = max(longestLen, len);
|
||||||
|
len = 0;
|
||||||
|
} else {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(listLine) longestLen = max(longestLen, len);
|
||||||
|
|
||||||
|
// Word wrap according to our target line length longestLen.
|
||||||
|
len = 0;
|
||||||
|
i = 0;
|
||||||
|
while(inBuf[i]) {
|
||||||
|
if(inBuf[i] == '\r') {
|
||||||
|
// ignore these
|
||||||
|
} else if(inBuf[i] == '\n') {
|
||||||
|
outBuf[j++] = '\n';
|
||||||
|
if(len == 0) rows++;
|
||||||
|
len = 0;
|
||||||
|
} else if(inBuf[i] == ' ' && len > longestLen) {
|
||||||
|
outBuf[j++] = '\n';
|
||||||
|
len = 0;
|
||||||
|
} else {
|
||||||
|
outBuf[j++] = inBuf[i];
|
||||||
|
// Count rows when we draw the first character; so an empty
|
||||||
|
// row doesn't end up counting.
|
||||||
|
if(len == 0) rows++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
cols = max(cols, len);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
outBuf[j++] = '\0';
|
||||||
|
|
||||||
|
// And then display the text with our actual longest line length.
|
||||||
|
DoMessageBox(outBuf, rows, cols, error);
|
||||||
|
}
|
||||||
|
void Error(char *str, ...)
|
||||||
|
{
|
||||||
|
va_list f;
|
||||||
|
va_start(f, str);
|
||||||
|
DoStringForMessageBox(str, f, true);
|
||||||
|
va_end(f);
|
||||||
|
}
|
||||||
|
void Message(char *str, ...)
|
||||||
|
{
|
||||||
|
va_list f;
|
||||||
|
va_start(f, str);
|
||||||
|
DoStringForMessageBox(str, f, false);
|
||||||
|
va_end(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Solve a mostly banded matrix. In a given row, there are LEFT_OF_DIAG
|
// Solve a mostly banded matrix. In a given row, there are LEFT_OF_DIAG
|
||||||
// elements to the left of the diagonal element, and RIGHT_OF_DIAG elements to
|
// elements to the left of the diagonal element, and RIGHT_OF_DIAG elements to
|
||||||
|
|
|
@ -58,42 +58,141 @@ HFONT FixedFont, LinkFont;
|
||||||
// The 6-DOF input device.
|
// The 6-DOF input device.
|
||||||
SiHdl SpaceNavigator = SI_NO_HANDLE;
|
SiHdl SpaceNavigator = SI_NO_HANDLE;
|
||||||
|
|
||||||
static void DoMessageBox(char *str, va_list f, BOOL error)
|
//-----------------------------------------------------------------------------
|
||||||
{
|
// Routines to display message boxes on screen. Do our own, instead of using
|
||||||
char buf[1024*50];
|
// MessageBox, because that is not consistent from version to version and
|
||||||
vsprintf(buf, str, f);
|
// there's word wrap problems.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HWND MessageWnd, OkButton;
|
||||||
|
BOOL MessageDone;
|
||||||
|
char *MessageString;
|
||||||
|
|
||||||
|
static LRESULT CALLBACK MessageProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
|
LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (msg) {
|
||||||
|
case WM_COMMAND:
|
||||||
|
if((HWND)lParam == OkButton && wParam == BN_CLICKED) {
|
||||||
|
MessageDone = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
case WM_DESTROY:
|
||||||
|
MessageDone = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_PAINT: {
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint(hwnd, &ps);
|
||||||
|
int row = 0, col = 0, i;
|
||||||
|
SelectObject(hdc, FixedFont);
|
||||||
|
SetTextColor(hdc, RGB(0, 0, 0));
|
||||||
|
SetBkMode(hdc, TRANSPARENT);
|
||||||
|
for(i = 0; MessageString[i]; i++) {
|
||||||
|
if(MessageString[i] == '\n') {
|
||||||
|
col = 0;
|
||||||
|
row++;
|
||||||
|
} else {
|
||||||
|
TextOut(hdc, col*TEXT_WIDTH + 10, row*TEXT_HEIGHT + 10,
|
||||||
|
&(MessageString[i]), 1);
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND CreateWindowClient(DWORD exStyle, char *className, char *windowName,
|
||||||
|
DWORD style, int x, int y, int width, int height, HWND parent,
|
||||||
|
HMENU menu, HINSTANCE instance, void *param)
|
||||||
|
{
|
||||||
|
HWND h = CreateWindowEx(exStyle, className, windowName, style, x, y,
|
||||||
|
width, height, parent, menu, instance, param);
|
||||||
|
|
||||||
|
RECT r;
|
||||||
|
GetClientRect(h, &r);
|
||||||
|
width = width - (r.right - width);
|
||||||
|
height = height - (r.bottom - height);
|
||||||
|
|
||||||
|
SetWindowPos(h, HWND_TOP, x, y, width, height, 0);
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoMessageBox(char *str, int rows, int cols, BOOL error)
|
||||||
|
{
|
||||||
EnableWindow(GraphicsWnd, FALSE);
|
EnableWindow(GraphicsWnd, FALSE);
|
||||||
EnableWindow(TextWnd, FALSE);
|
EnableWindow(TextWnd, FALSE);
|
||||||
|
|
||||||
int flags;
|
|
||||||
if(error) {
|
|
||||||
flags = MB_OK | MB_ICONERROR;
|
|
||||||
} else {
|
|
||||||
flags = MB_OK | MB_ICONINFORMATION;
|
|
||||||
}
|
|
||||||
HWND h = GetForegroundWindow();
|
HWND h = GetForegroundWindow();
|
||||||
MessageBox(h, buf, "SolveSpace", flags);
|
|
||||||
|
|
||||||
|
// Register the window class for our dialog.
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
memset(&wc, 0, sizeof(wc));
|
||||||
|
wc.cbSize = sizeof(wc);
|
||||||
|
wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC;
|
||||||
|
wc.lpfnWndProc = (WNDPROC)MessageProc;
|
||||||
|
wc.hInstance = Instance;
|
||||||
|
wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
|
||||||
|
wc.lpszClassName = "MessageWnd";
|
||||||
|
wc.lpszMenuName = NULL;
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wc.hIcon = (HICON)LoadImage(Instance, MAKEINTRESOURCE(4000),
|
||||||
|
IMAGE_ICON, 32, 32, 0);
|
||||||
|
wc.hIconSm = (HICON)LoadImage(Instance, MAKEINTRESOURCE(4000),
|
||||||
|
IMAGE_ICON, 16, 16, 0);
|
||||||
|
RegisterClassEx(&wc);
|
||||||
|
|
||||||
|
// Create the window.
|
||||||
|
MessageString = str;
|
||||||
|
RECT r;
|
||||||
|
GetWindowRect(GraphicsWnd, &r);
|
||||||
|
char *title = error ? "SolveSpace - Error" : "SolveSpace - Message";
|
||||||
|
int width = cols*TEXT_WIDTH + 20, height = rows*TEXT_HEIGHT + 60;
|
||||||
|
MessageWnd = CreateWindowClient(0, "MessageWnd", title,
|
||||||
|
WS_OVERLAPPED | WS_SYSMENU,
|
||||||
|
r.left + 100, r.top + 100, width, height, NULL, NULL, Instance, NULL);
|
||||||
|
|
||||||
|
OkButton = CreateWindowEx(0, WC_BUTTON, "OK",
|
||||||
|
WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON,
|
||||||
|
(width - 70)/2, rows*TEXT_HEIGHT + 20,
|
||||||
|
70, 25, MessageWnd, NULL, Instance, NULL);
|
||||||
|
SendMessage(OkButton, WM_SETFONT, (WPARAM)FixedFont, TRUE);
|
||||||
|
|
||||||
|
ShowWindow(MessageWnd, TRUE);
|
||||||
|
SetFocus(OkButton);
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
DWORD ret;
|
||||||
|
MessageDone = FALSE;
|
||||||
|
while((ret = GetMessage(&msg, NULL, 0, 0)) && !MessageDone) {
|
||||||
|
if((msg.message == WM_KEYDOWN &&
|
||||||
|
(msg.wParam == VK_RETURN ||
|
||||||
|
msg.wParam == VK_ESCAPE)) ||
|
||||||
|
(msg.message == WM_KEYUP &&
|
||||||
|
(msg.wParam == VK_SPACE)))
|
||||||
|
{
|
||||||
|
MessageDone = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageString = NULL;
|
||||||
EnableWindow(TextWnd, TRUE);
|
EnableWindow(TextWnd, TRUE);
|
||||||
EnableWindow(GraphicsWnd, TRUE);
|
EnableWindow(GraphicsWnd, TRUE);
|
||||||
SetForegroundWindow(GraphicsWnd);
|
SetForegroundWindow(GraphicsWnd);
|
||||||
}
|
DestroyWindow(MessageWnd);
|
||||||
|
|
||||||
void Error(char *str, ...)
|
|
||||||
{
|
|
||||||
va_list f;
|
|
||||||
va_start(f, str);
|
|
||||||
DoMessageBox(str, f, TRUE);
|
|
||||||
va_end(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message(char *str, ...)
|
|
||||||
{
|
|
||||||
va_list f;
|
|
||||||
va_start(f, str);
|
|
||||||
DoMessageBox(str, f, FALSE);
|
|
||||||
va_end(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddContextMenuItem(char *label, int id)
|
void AddContextMenuItem(char *label, int id)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
better Error() and Message() dialog boxes
|
replace show/hide links with icons?
|
||||||
lock point where dragged constraint
|
lock point where dragged constraint
|
||||||
projected and signed distance constraints
|
projected and signed distance constraints
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user