Have the application do a single BAlert on a BApplication::QuitRequested()-event in multi-window situations. Move reading/writing of settings from window to application. Cascade-offset the most recent window when they collide.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32092 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "ZipOMatic.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <TrackerAddOn.h>
|
||||
|
||||
#include "ZipOMaticMisc.h"
|
||||
@@ -39,15 +41,24 @@ main()
|
||||
ZipOMatic::ZipOMatic()
|
||||
:
|
||||
BApplication(ZIPOMATIC_APP_SIG),
|
||||
fGotRefs(false)
|
||||
fSettings(),
|
||||
fGotRefs(false),
|
||||
fInvoker(new BInvoker(new BMessage(ZIPPO_QUIT_OR_CONTINUE), NULL, this)),
|
||||
fWindowFrame(200, 200, 430, 310)
|
||||
{
|
||||
|
||||
status_t status = _ReadSettings();
|
||||
|
||||
if (status != B_OK)
|
||||
ErrorMessage("_ReadSettings()", status);
|
||||
}
|
||||
|
||||
|
||||
ZipOMatic::~ZipOMatic()
|
||||
{
|
||||
|
||||
status_t status = _WriteSettings();
|
||||
|
||||
if (status != B_OK)
|
||||
ErrorMessage("_WriteSettings()", status);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,15 +87,32 @@ ZipOMatic::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case ZIPPO_WINDOW_QUIT:
|
||||
{
|
||||
BRect frame;
|
||||
if (message->FindRect("frame", &frame) == B_OK)
|
||||
fWindowFrame = frame;
|
||||
snooze(200000);
|
||||
if (CountWindows() == 0)
|
||||
Quit();
|
||||
break;
|
||||
|
||||
}
|
||||
case B_SILENT_RELAUNCH:
|
||||
_SilentRelaunch();
|
||||
break;
|
||||
|
||||
case ZIPPO_QUIT_OR_CONTINUE:
|
||||
{
|
||||
int32 button;
|
||||
if (message->FindInt32("which", &button) == B_OK)
|
||||
if (button == 0) {
|
||||
_StopZipping();
|
||||
} else {
|
||||
if (CountWindows() == 0)
|
||||
Quit();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(message);
|
||||
break;
|
||||
@@ -95,33 +123,73 @@ ZipOMatic::MessageReceived(BMessage* message)
|
||||
bool
|
||||
ZipOMatic::QuitRequested (void)
|
||||
{
|
||||
// Overriding BApplication's default behaviour on purpose
|
||||
// so we can have multiple zippers pause in unison.
|
||||
|
||||
if (CountWindows() <= 0)
|
||||
return true;
|
||||
|
||||
BList list(5);
|
||||
BWindow* window;
|
||||
ZippoWindow* zippo;
|
||||
ZippoWindow* lastFoundZippo;
|
||||
int32 zippoCount = 0;
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
window = WindowAt(i);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
list.AddItem(window);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
window = (BWindow*) list.RemoveItem(int32(0));
|
||||
window = WindowAt(i);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
if (window->Lock()) {
|
||||
window->PostMessage(B_QUIT_REQUESTED);
|
||||
window->Unlock();
|
||||
zippo = dynamic_cast<ZippoWindow*>(window);
|
||||
if (zippo == NULL)
|
||||
continue;
|
||||
|
||||
lastFoundZippo = zippo;
|
||||
|
||||
if (zippo->Lock()) {
|
||||
if (zippo->IsZipping())
|
||||
zippoCount++;
|
||||
else
|
||||
zippo->PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
zippo->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (zippoCount == 1) {
|
||||
// This is likely the most frequent case - a single zipper.
|
||||
// We post a message to the window so it can put up its own
|
||||
// BAlert instead of the app-wide BAlert. This avoids making
|
||||
// a difference between having pressed Commmand-W or Command-Q.
|
||||
// Closing or quitting, it doesn't matter for a single window.
|
||||
|
||||
if (lastFoundZippo->Lock()) {
|
||||
lastFoundZippo->Activate();
|
||||
lastFoundZippo->PostMessage(B_QUIT_REQUESTED);
|
||||
lastFoundZippo->Unlock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zippoCount > 0) {
|
||||
// The multi-zipper case differs from the single-zipper case
|
||||
// in that zippers are not paused while the BAlert is up.
|
||||
|
||||
BString question;
|
||||
question << "You have " << zippoCount;
|
||||
question << " Zip-O-Matic running.\n\nDo you want to stop them?";
|
||||
|
||||
BAlert* alert = new BAlert("Stop or Continue", question.String(),
|
||||
"Stop them", "Let them continue", NULL, B_WIDTH_AS_USUAL,
|
||||
B_WARNING_ALERT);
|
||||
alert->Go(fInvoker);
|
||||
alert->Activate();
|
||||
// BAlert, being modal, does not show on the current workspace
|
||||
// if the application has no window there. Activate() triggers
|
||||
// a switch to a workspace where it does have a window.
|
||||
|
||||
// TODO: See if AS_ACTIVATE_WINDOW should be handled differently
|
||||
// in src/servers/app/Desktop.cpp Desktop::ActivateWindow()
|
||||
// or if maybe BAlert should (and does not?) activate itself.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CountWindows() <= 0)
|
||||
return true;
|
||||
@@ -154,6 +222,7 @@ ZipOMatic::_UseExistingOrCreateNewWindow(BMessage* message)
|
||||
foundNonBusyWindow = true;
|
||||
if (message != NULL)
|
||||
window->PostMessage(message);
|
||||
window->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
window->Activate();
|
||||
window->Unlock();
|
||||
break;
|
||||
@@ -164,8 +233,143 @@ ZipOMatic::_UseExistingOrCreateNewWindow(BMessage* message)
|
||||
|
||||
if (!foundNonBusyWindow)
|
||||
{
|
||||
ZippoWindow * window = new ZippoWindow(message);
|
||||
BScreen screen;
|
||||
fWindowFrame.OffsetBy(screen.Frame().LeftTop());
|
||||
|
||||
_CascadeOnFrameCollision(&fWindowFrame);
|
||||
if(!screen.Frame().Contains(fWindowFrame)) {
|
||||
fWindowFrame.OffsetTo(screen.Frame().LeftTop());
|
||||
fWindowFrame.OffsetBy(20,45);
|
||||
// TODO: replace with CenterOnScreen()
|
||||
}
|
||||
|
||||
ZippoWindow * window = new ZippoWindow(fWindowFrame, message);
|
||||
window->Show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZipOMatic::_StopZipping()
|
||||
{
|
||||
BWindow* window;
|
||||
ZippoWindow* zippo;
|
||||
BList list;
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
window = WindowAt(i);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
zippo = dynamic_cast<ZippoWindow*>(window);
|
||||
if (zippo == NULL)
|
||||
continue;
|
||||
|
||||
list.AddItem(zippo);
|
||||
}
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
zippo = static_cast<ZippoWindow*>(list.ItemAt(i));
|
||||
if (zippo == NULL)
|
||||
break;
|
||||
|
||||
if (zippo->Lock()) {
|
||||
if (zippo->IsZipping())
|
||||
zippo->StopZipping();
|
||||
|
||||
zippo->PostMessage(B_QUIT_REQUESTED);
|
||||
zippo->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZipOMatic::_ReadSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.SetTo("zipomatic.msg");
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.ReadSettings();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BRect frame;
|
||||
status = fSettings.FindRect("frame", &frame);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fWindowFrame = frame;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZipOMatic::_WriteSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.MakeEmpty();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.AddRect("frame", fWindowFrame);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSettings.WriteSettings();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZipOMatic::_CascadeOnFrameCollision(BRect* frame)
|
||||
{
|
||||
BWindow* window;
|
||||
ZippoWindow* zippo;
|
||||
BList list;
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
window = WindowAt(i);
|
||||
if (window == NULL)
|
||||
break;
|
||||
|
||||
zippo = dynamic_cast<ZippoWindow*>(window);
|
||||
if (zippo == NULL)
|
||||
continue;
|
||||
|
||||
list.AddItem(zippo);
|
||||
}
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
zippo = static_cast<ZippoWindow*>(list.ItemAt(i));
|
||||
if (zippo == NULL)
|
||||
break;
|
||||
|
||||
if (zippo->Lock()) {
|
||||
if (frame->LeftTop() == zippo->Frame().LeftTop())
|
||||
frame->OffsetBy(20, 20);
|
||||
zippo->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
#include <Invoker.h>
|
||||
#include <Message.h>
|
||||
#include <Rect.h>
|
||||
|
||||
#include "ZipOMaticSettings.h"
|
||||
|
||||
|
||||
class ZipOMatic : public BApplication
|
||||
@@ -18,11 +22,18 @@ public:
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
status_t _ReadSettings();
|
||||
status_t _WriteSettings();
|
||||
void _CascadeOnFrameCollision(BRect* frame);
|
||||
void _SilentRelaunch();
|
||||
void _UseExistingOrCreateNewWindow(BMessage*
|
||||
message = NULL);
|
||||
void _StopZipping();
|
||||
|
||||
ZippoSettings fSettings;
|
||||
bool fGotRefs;
|
||||
BInvoker* fInvoker;
|
||||
BRect fWindowFrame;
|
||||
};
|
||||
|
||||
#endif // _ZIPOMATIC_H_
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#define ZIPOMATIC_APP_SIG "application/x-vnd.haiku.zip-o-matic"
|
||||
|
||||
#define ZIPPO_WINDOW_QUIT 'winq'
|
||||
#define ZIPPO_QUIT_OR_CONTINUE 'alrt'
|
||||
#define ZIPPO_THREAD_EXIT 'exit'
|
||||
#define ZIPPO_THREAD_EXIT_ERROR 'exrr'
|
||||
#define ZIPPO_TASK_DESCRIPTION 'strt'
|
||||
#define ZIPPO_LINE_OF_STDOUT 'outp'
|
||||
|
||||
status_t FindAndCreateDirectory(directory_which which,
|
||||
BVolume* volume = NULL, const char* relativePath = NULL,
|
||||
|
||||
@@ -28,39 +28,26 @@
|
||||
#include "ZipperThread.h"
|
||||
|
||||
|
||||
ZippoWindow::ZippoWindow(BMessage* message)
|
||||
ZippoWindow::ZippoWindow(BRect frame, BMessage* refs)
|
||||
:
|
||||
BWindow(BRect(200, 200, 430, 310), "Zip-O-Matic", B_TITLED_WINDOW,
|
||||
B_NOT_V_RESIZABLE),
|
||||
BWindow(frame, "Zip-O-Matic", B_TITLED_WINDOW, B_NOT_V_RESIZABLE),
|
||||
fView(NULL),
|
||||
fSettings(),
|
||||
fThread(NULL),
|
||||
fWindowGotRefs(false),
|
||||
fZippingWasStopped(false),
|
||||
fWindowInvoker(new BInvoker(new BMessage('alrt'), NULL, this))
|
||||
fWindowInvoker(new BInvoker(new BMessage(ZIPPO_QUIT_OR_CONTINUE), NULL,
|
||||
this))
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.SetTo("ZipOMatic.msg");
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.SetTo()", status);
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.InitCheck()", status);
|
||||
|
||||
fView = new ZippoView(Bounds());
|
||||
AddChild(fView);
|
||||
|
||||
SetSizeLimits(Bounds().Width(), 15000, Bounds().Height(),
|
||||
Bounds().Height());
|
||||
|
||||
_ReadSettings();
|
||||
|
||||
if (message != NULL)
|
||||
if (refs != NULL)
|
||||
{
|
||||
fWindowGotRefs = true;
|
||||
_StartZipping(message);
|
||||
_StartZipping(refs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +75,7 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'exit':
|
||||
// thread has finished - (finished, quit, killed, we don't know)
|
||||
case ZIPPO_THREAD_EXIT:
|
||||
fThread = NULL;
|
||||
fView->fActivityView->Stop();
|
||||
fView->fStopButton->SetEnabled(false);
|
||||
@@ -102,7 +88,8 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
_CloseWindowOrKeepOpen();
|
||||
break;
|
||||
|
||||
case 'exrr': // thread has finished - badly
|
||||
case ZIPPO_THREAD_EXIT_ERROR:
|
||||
// TODO: figure out why this case does not happen when it should
|
||||
fThread = NULL;
|
||||
fView->fActivityView->Stop();
|
||||
fView->fStopButton->SetEnabled(false);
|
||||
@@ -110,7 +97,7 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
fView->fZipOutputView->SetText("Error creating archive");
|
||||
break;
|
||||
|
||||
case 'strt':
|
||||
case ZIPPO_TASK_DESCRIPTION:
|
||||
{
|
||||
BString string;
|
||||
if (message->FindString("archive_filename", &string) == B_OK)
|
||||
@@ -118,7 +105,7 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case 'outp':
|
||||
case ZIPPO_LINE_OF_STDOUT:
|
||||
{
|
||||
BString string;
|
||||
if (message->FindString("zip_output", &string) == B_OK)
|
||||
@@ -126,12 +113,12 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case 'alrt':
|
||||
case ZIPPO_QUIT_OR_CONTINUE:
|
||||
{
|
||||
int32 which_button = -1;
|
||||
if (message->FindInt32("which", &which_button) == B_OK) {
|
||||
if (which_button == 0) {
|
||||
_StopZipping();
|
||||
StopZipping();
|
||||
} else {
|
||||
if (fThread != NULL)
|
||||
fThread->ResumeExternalZip();
|
||||
@@ -152,85 +139,25 @@ ZippoWindow::MessageReceived(BMessage* message)
|
||||
bool
|
||||
ZippoWindow::QuitRequested()
|
||||
{
|
||||
if (fThread == NULL) {
|
||||
_WriteSettings();
|
||||
be_app_messenger.SendMessage(ZIPPO_WINDOW_QUIT);
|
||||
if (!IsZipping()) {
|
||||
BMessage message(ZIPPO_WINDOW_QUIT);
|
||||
message.AddRect("frame", Frame());
|
||||
be_app_messenger.SendMessage(&message);
|
||||
return true;
|
||||
} else {
|
||||
if (fThread != NULL)
|
||||
fThread->SuspendExternalZip();
|
||||
|
||||
fThread->SuspendExternalZip();
|
||||
fView->fActivityView->Pause();
|
||||
|
||||
|
||||
BAlert* alert = new BAlert("Stop or Continue",
|
||||
"Are you sure you want to stop creating this archive?", "Stop",
|
||||
"Continue", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||
alert->Go(fWindowInvoker);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoWindow::_ReadSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.InitCheck()", status);
|
||||
|
||||
status = fSettings.ReadSettings();
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.ReadSettings()", status);
|
||||
|
||||
BRect windowRect;
|
||||
|
||||
status = fSettings.FindRect("windowRect", &windowRect);
|
||||
if (status != B_OK)
|
||||
{
|
||||
ErrorMessage("fSettings.FindRect(windowRect)", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
ResizeTo(windowRect.Width(), windowRect.Height());
|
||||
MoveTo(windowRect.LeftTop());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ZippoWindow::_WriteSettings()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = fSettings.InitCheck();
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.InitCheck()", status);
|
||||
|
||||
status = fSettings.MakeEmpty();
|
||||
if (status != B_OK)
|
||||
ErrorMessage("fSettings.MakeEmpty()", status);
|
||||
|
||||
status = fSettings.AddRect("windowRect", Frame());
|
||||
if (status != B_OK)
|
||||
{
|
||||
ErrorMessage("fSettings.AddRect(windowRect)", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = fSettings.WriteSettings();
|
||||
if (status != B_OK)
|
||||
{
|
||||
ErrorMessage("fSettings.WriteSettings()", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZippoWindow::_StartZipping(BMessage* message)
|
||||
{
|
||||
@@ -245,7 +172,7 @@ ZippoWindow::_StartZipping(BMessage* message)
|
||||
|
||||
|
||||
void
|
||||
ZippoWindow::_StopZipping()
|
||||
ZippoWindow::StopZipping()
|
||||
{
|
||||
fZippingWasStopped = true;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <MenuItem.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "ZipOMaticSettings.h"
|
||||
#include "ZipOMaticView.h"
|
||||
#include "ZipperThread.h"
|
||||
|
||||
@@ -16,7 +15,7 @@
|
||||
class ZippoWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
ZippoWindow(BMessage* message = NULL);
|
||||
ZippoWindow(BRect frame, BMessage* refs = NULL);
|
||||
~ZippoWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
@@ -24,18 +23,14 @@ public:
|
||||
virtual void Zoom(BPoint origin, float width, float height);
|
||||
|
||||
bool IsZipping();
|
||||
void StopZipping();
|
||||
|
||||
private:
|
||||
status_t _ReadSettings();
|
||||
status_t _WriteSettings();
|
||||
|
||||
void _StartZipping(BMessage* message);
|
||||
void _StopZipping();
|
||||
|
||||
void _CloseWindowOrKeepOpen();
|
||||
|
||||
ZippoView* fView;
|
||||
ZippoSettings fSettings;
|
||||
ZipperThread* fThread;
|
||||
|
||||
bool fWindowGotRefs;
|
||||
|
||||
@@ -140,8 +140,10 @@ ZipperThread::ThreadStartup()
|
||||
|
||||
archiveName.Prepend("Creating archive: ");
|
||||
|
||||
_SendMessageToWindow('strt', "archive_filename", archiveName.String());
|
||||
_SendMessageToWindow('outp', "zip_output", "Preparing to archive");
|
||||
_SendMessageToWindow(ZIPPO_TASK_DESCRIPTION, "archive_filename",
|
||||
archiveName.String());
|
||||
_SendMessageToWindow(ZIPPO_LINE_OF_STDOUT, "zip_output",
|
||||
"Preparing to archive");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -164,12 +166,12 @@ ZipperThread::ExecuteUnit()
|
||||
|
||||
if (!strncmp(" a", output, 3)) {
|
||||
output[2] = 'A';
|
||||
_SendMessageToWindow('outp', "zip_output", output + 2);
|
||||
_SendMessageToWindow(ZIPPO_LINE_OF_STDOUT, "zip_output", output + 2);
|
||||
} else if (!strncmp("up", output, 2)) {
|
||||
output[0] = 'U';
|
||||
_SendMessageToWindow('outp', "zip_output", output);
|
||||
_SendMessageToWindow(ZIPPO_LINE_OF_STDOUT, "zip_output", output);
|
||||
} else {
|
||||
_SendMessageToWindow('outp', "zip_output", output);
|
||||
_SendMessageToWindow(ZIPPO_LINE_OF_STDOUT, "zip_output", output);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@@ -202,10 +204,10 @@ ZipperThread::ExecuteUnitFailed(status_t status)
|
||||
|
||||
if (status == EOF) {
|
||||
// thread has finished, been quit or killed, we don't know
|
||||
_SendMessageToWindow('exit');
|
||||
_SendMessageToWindow(ZIPPO_THREAD_EXIT);
|
||||
} else {
|
||||
// explicit error - communicate error to Window
|
||||
_SendMessageToWindow('exrr');
|
||||
_SendMessageToWindow(ZIPPO_THREAD_EXIT_ERROR);
|
||||
}
|
||||
|
||||
Quit();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "GenericThread.h"
|
||||
|
||||
Reference in New Issue
Block a user