ribi::ProjectRichelBilderbeekMenuDialog::ProjectRichelBilderbeekMenuDialog()
  : m_menus(CreateMenus())
{
  #ifndef NDEBUG
  Test();
  for (const auto& p: CreateMenus())
  {
    assert(p || !p);
  }
  #endif
}
Ejemplo n.º 2
0
int
main(int    argc,
     char **argv)
{
 XtAppContext app_context;
 Widget       main_window;

   XtSetLanguageProc(NULL, NULL, NULL);
   top_level = XtVaOpenApplication(&app_context, APP_CLASS, 
                                NULL, 0, &argc, argv, 
                                NULL,
                                sessionShellWidgetClass, 
                                NULL);
   XmdRegisterEditres(top_level);
   main_window = XtVaCreateManagedWidget("main_window", 
                                xmMainWindowWidgetClass, top_level,
                                NULL);

   CreateMenus(main_window);
   CreateNotebook(main_window);

   XtRealizeWidget(top_level);
   XtAppMainLoop(app_context);

   return 0;    /* make compiler happy */
}
Ejemplo n.º 3
0
SegMainWindow::SegMainWindow(QWidget *parent) :
QMainWindow(parent)
{
	label = new QLabel("Seg Tool");
	QHBoxLayout * layout = new QHBoxLayout(this);;
	multiViewWgt = new QmitkStdMultiWidget;


	QWidget *centerWgt = new QWidget;
	layout->addWidget(multiViewWgt);

	centerWgt->setLayout(layout);
	this->setCentralWidget(centerWgt);
	//this->setLayout(layout);
	this->setMinimumSize(800,600);

	m_DataStorage = mitk::StandaloneDataStorage::New();
	multiViewWgt->SetDataStorage(m_DataStorage);
	// Initialize bottom-right view as 3D view
	multiViewWgt->GetRenderWindow4()->GetRenderer()->SetMapperID(
		mitk::BaseRenderer::Standard3D);

	// Enable standard handler for levelwindow-slider
	multiViewWgt->EnableStandardLevelWindow();
	multiViewWgt->SetWidgetPlanesVisibility(true);
	multiViewWgt->DisableDepartmentLogo();
	
	CreateActions();
	CreateMenus();
	m_FirstImage = nullptr;
	m_ResultImage = nullptr;
	m_ResultNode = nullptr;
}
Ejemplo n.º 4
0
ObjectWorkspace::ObjectWorkspace()
  : mLoadShaderDefAction(NULL)
  , mLoadGeometryAction(NULL)
  , mExitAct(NULL)
{
   resize(1024, 768);

   mResourceDock = new ResourceDock;
   addDockWidget(Qt::LeftDockWidgetArea, mResourceDock);

   // Create all program actions
   CreateFileMenuActions();
   CreateModeToolbarActions();
   CreateEditingToolbarAction();
   CreateDisplayToolbarActions();
   CreateShaderToolbarActions();

   CreateMenus();
   statusBar();
   CreateToolbars();

   QWidget* glParent = new QWidget();

   mCentralLayout = new QHBoxLayout();
   mCentralLayout->setMargin(0);
   glParent->setLayout(mCentralLayout);
   setCentralWidget(glParent);

   setAcceptDrops(true);
}
Ejemplo n.º 5
0
FB_Frame::FB_Frame( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) :
    wxFrame( parent, id, caption, pos, size, style ) {
    wxSystemOptions::SetOption(wxT("msw.notebook.themed-background"), 0);
    m_Config = new FB_Config(  );
    m_DocList = new FB_DocList;
    m_StatusBar = new FB_StatusBar( this );
    m_ToolBar = new FB_ToolBar( this );
        
    if ( m_Config->winw==-1||m_Config->winh==-1 ) {
        SetSize(300, 200);
        Centre();
        Maximize();
    }
    else {
        Move(m_Config->winx, m_Config->winy);
        SetSize(m_Config->winw, m_Config->winh);
    }
    Show( true );
        
    m_Code_area = NULL;
    m_ActiveTabID = -1;
    
    Freeze();
        CreateMenus();
        CreateToolbar();
        CreatePanels();
        CreateStatusBar();
    Thaw();

    SendSizeEvent();
    SetStatus();
    m_Config->m_FileHistory->AddFilesToMenu();
}
Ejemplo n.º 6
0
int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	
	InitDisplay();
	
    // setup haptic renderer
    InitHL();

	HandleMenuCommand('d'); // reset the surface properties to default

	//mPS.StartConstructingSystem();
	//mDesign = true;
	ConstructSurface(mSurfaceParticles);
	mPause = false;

	// create pulldown menus
	CreateMenus();

    /* The GLUT main loop won't return control, so we need to perform cleanup
       using an exit handler. */
    atexit(exitHandler);

    // turn over control to GLUT
	glutMainLoop();

	return 0;             
}
Ejemplo n.º 7
0
/* main() */
int
main (int argc, char **argv)
{
 XtAppContext  app;
 Display      *display;

 XtAppContext app_context;
 Widget       main_window;

   XtSetLanguageProc(NULL, NULL, NULL);
   top_level = XtVaOpenApplication(&app_context, APP_CLASS, 
                                NULL, 0, &argc, argv, 
                                fallbacks, sessionShellWidgetClass,
                                NULL);
   XmdRegisterEditres(top_level);
   main_window = XtVaCreateManagedWidget("main_window", 
                                xmMainWindowWidgetClass, top_level,
                                NULL);

   CreateMenus(main_window);
   CreateSpinBoxes(main_window);

   XtRealizeWidget(top_level);
   XtAppMainLoop(app_context);
   exit(0);
}
void ribi::ProjectRichelBilderbeekMenuDialog::ShowStatus() const noexcept
{
  typedef boost::shared_ptr<const ribi::Program> ProgramType;

  std::vector<ProgramType> v;
  for (const auto& p: CreateMenus())
  {
    assert(p);
    assert(p->GetProgram());
    v.push_back(p->GetProgram());
  }
  assert(v.size() == CreateMenus().size());

  //Find out the padding
  const int max_length {
    static_cast<int>(
      (*std::max_element(v.begin(),v.end(),
        [](const ProgramType& lhs,const ProgramType& rhs)
        {
          return lhs->GetName().size() < rhs->GetName().size();
        }
      ))->GetName().size()
    )
  };


  for (const ProgramType& p: v)
  {
    const std::string name_no_padding = p->GetName();
    const int cur_length = static_cast<int>(name_no_padding.size());
    const int n_spaces { max_length - cur_length };
    assert(n_spaces >= 0);
    const std::string name {
      cur_length == max_length
      ? name_no_padding
      : name_no_padding + std::string(n_spaces,' ')
    };
    std::cout
       << name
       << '\t' << p->GetTypeName()
       << '\t' << ProgramStatusToStr(p->GetStatusConsole())
       << '\t' << ProgramStatusToStr(p->GetStatusDesktopWindowsOnly())
       << '\t' << ProgramStatusToStr(p->GetStatusDesktop())
       << '\t' << ProgramStatusToStr(p->GetStatusWebApplication())
       << '\n';
  }
}
Ejemplo n.º 9
0
//!
//! \brief MainWindow::MainWindow
//! \param parent
//! Construct the main window and child widgets
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    CreateWidgets();
    CreateActions();
    CreateMenus();
    CreateToolbars();
}
Ejemplo n.º 10
0
MyFrame::MyFrame( wxWindow *parent, wxWindowID id, const wxString &title,
                  const wxPoint &position, const wxSize& size, long style )
        :wxFrame( parent, id, title, position, size, style )
{
    m_preview_state = ID_PREVIEW;

    // set the frame icon
    SetIcon(wxICON(mondrian));

    SetMinSize(wxSize(200, 200));

    // set-up the menu, toolbar, statusbar so we know what the client size will be
    m_menubar = new wxMenuBar();
    SetMenuBar(m_menubar);
    m_toolBar = CreateToolBar();

#if wxUSE_STATUSBAR
    CreateStatusBar(2);
    int status_text_width = 0, status_text_height = 0;
    GetStatusBar()->GetTextExtent(MyVideoCaptureWindow::GetStatusText(999999, 9999),
                                  &status_text_width, &status_text_height);
    int status_widths[2] = {-1, status_text_width};
    SetStatusWidths(2, status_widths);
#endif // wxUSE_STATUSBAR

    m_splitterWin = new wxSplitterWindow(this, wxID_ANY);
    m_splitterWin->SetMinimumPaneSize(20);

    m_logPanel = new wxPanel( m_splitterWin, wxID_ANY );
    wxBoxSizer *logpanelsizer = new wxBoxSizer(wxVERTICAL);
    m_logTextCtrl = new wxTextCtrl(m_logPanel, wxID_ANY,
                                   wxT("Event Log for wxVideoCaptureWindow : \n"),
                                   wxDefaultPosition, wxDefaultSize,
                                   wxTE_MULTILINE|wxTE_RICH2|wxTE_READONLY );
    logpanelsizer->Add(m_logTextCtrl, 1, wxEXPAND);
    m_logPanel->SetAutoLayout( true );
    m_logPanel->SetSizer(logpanelsizer);
    logpanelsizer->Fit( m_logPanel );
    logpanelsizer->SetSizeHints( m_logPanel );

    m_vidCapWin = new MyVideoCaptureWindow( m_splitterWin, ID_VIDEOWIN,
                                            wxDefaultPosition, wxDefaultSize);

#ifdef WXVIDCAP_AVI_SUPPORT
    SetTitle(wxT("wxVidCap - ") + m_vidCapWin->GetCaptureFilename());
#else
    SetTitle(wxT("wxVidCap"));
#endif // WXVIDCAP_AVI_SUPPORT

    m_logPanel->Show(false);
    m_vidCapWin->Show(true);
    m_splitterWin->Initialize(m_vidCapWin);

    CreateMenus();
    CreateToolbar();
    SetupVideoMenus();
}
Ejemplo n.º 11
0
MainMenu::MainMenu(FXComposite* p, MenuMgr*mmgr, FXRegistry*r):FXMenuBar(p,LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
{
  tw=(TopWindow*)p;
  mnumgr=mmgr;
  reg=r;
  prefs=SettingsBase::instance();
  CreateMenus();
  new FXHorizontalSeparator(p,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE);
}
Ejemplo n.º 12
0
MainWindow::MainWindow()
  : QMainWindow()
{
  resize(800, 600);
  CreateActions();
  CreateMenus();
  CreateToolBars();
  CreateStatusBar();

}
Ejemplo n.º 13
0
// MainWindow ctor
//////////////////
MainWindow::MainWindow(QWidget *parent, const char *name)
   : QMainWindow(parent, name)
{

   // Set the applications icon
   setIcon(QPixmap::fromMimeSource("applogo.png"));

   // Here we create and set the main widget
   twManager = new QTabWidget(this, "Window Manager");
   setCentralWidget(twManager);

   testb = new QTextBrowser(this, "Test");
   testb->mimeSourceFactory()->setFilePath(".");
   testb->mimeSourceFactory()->setImage("startpage-title", QImage::fromMimeSource("startpage-title.png"));
   testb->setSource("test.htm");
   twManager->addTab(testb, testb->documentTitle());

   // Create the Solution Explorer Dock Window
   SolutionExplorer = new CSolutionExplorer(this);
   SolutionExplorer->setCaption("Solution Explorer");
   SolutionExplorer->setHorizontallyStretchable(true);
   SolutionExplorer->setResizeEnabled(true);
   SolutionExplorer->setCloseMode(QDockWindow::Always);
   moveDockWindow(SolutionExplorer, Left);

   // Create the output dock wndow
   OutputWindow = new COutputWindow(this);
   OutputWindow->setCaption("Output");
   OutputWindow->setVerticallyStretchable(true);
   OutputWindow->setResizeEnabled(true);
   OutputWindow->setCloseMode(QDockWindow::Always);
   moveDockWindow(OutputWindow, Bottom);
   OutputWindow->hide(); // Hide the window by default

   // Create all actions
   if(!CreateActions())
     close();

   // Create the status bar
   if(!CreateStatusbar())
     close();

   // Now we create all MainWindow toolbars
   if(!CreateToolbars())
     close();

   // Now we create all MainWindow Menus
   if(!CreateMenus())
     close();

   // Resize the window
   resize(600,400);


}
Ejemplo n.º 14
0
Viewer::Viewer(QWidget* parent) :
  QMainWindow(parent),
  resources_(ResourceManager::Create()),
  default_scene_(resources_->MakeScene("default_scene")),
  viewport_(new Viewport(resources_, default_scene_, this)) {
  // Add a couple lights
  LightNode* light0 = default_scene_->MakeLight(default_scene_->Root());
  light0->SetDirection(QVector3D(1, 1, -1));
  light0->SetLightType(LightType::kDirectional);
  light0->SetAmbient(0.05);

  // Add a camera to the scene
  CameraNode* camera = default_scene_->MakeCamera(default_scene_->Root());

  // Set the camera perspective projection parameters, and point it somewhere.
  const QVector3D eye(5, 5, -10);
  const QVector3D look_at(0, 0, 0);
  const QVector3D up(0, 0, -1);
  camera->LookAt(eye, look_at, up);
  camera->SetProjectionParams(CameraNode::kPerspective, 50, 0.1, 5000);

  // Assign the camera to the viewport
  viewport_->SetCamera(camera);

  // Add a renderer widget stack
  renderer_widget_stack_ = new RendererWidgetStack(this);

  // Whenever a renderer is added to the viewport, add its widget to
  // the renderer widget stack and a menu entry.
  connect(viewport_, &Viewport::RendererAdded,
      this, &Viewer::OnRendererAdded);

  // Similarly, whenever an input handler is added to the viewport, add
  // a menu entry.
  connect(viewport_, &Viewport::InputHandlerAdded,
      this, &Viewer::OnInputHandlerAdded);
  connect(viewport_, &Viewport::InputHandlerActivated,
      this, &Viewer::OnInputHandlerActivated);

  setCentralWidget(viewport_);

  addDockWidget(Qt::LeftDockWidgetArea, renderer_widget_stack_);

  // Add the input controls dock widget
  input_handler_widget_ = new InputHandlerWidgetStack(viewport_, this);

  addDockWidget(Qt::LeftDockWidgetArea, input_handler_widget_);

  CreateMenus();

  resize(800, 600);
}
Ejemplo n.º 15
0
static int vsid_menu_create(void)
{
    struct Screen* pubscreen = NULL;
    int i, j;

    pubscreen = LockPubScreen(NULL);

    if (pubscreen == NULL) {
        return -1;
    }

    if (!(VisualInfo = GetVisualInfo(pubscreen, TAG_DONE))) {
        return -1;
    }

    for (i = 0, j = 0; vsid_ui_translation_menu[i].nm_Type != NM_END; i++) {
        vsid_ui_menu[j].nm_Type = vsid_ui_translation_menu[i].nm_Type;
        vsid_ui_menu[j].nm_CommKey = vsid_ui_translation_menu[i].nm_CommKey;
        vsid_ui_menu[j].nm_Flags = vsid_ui_translation_menu[i].nm_Flags;
        vsid_ui_menu[j].nm_MutualExclude = vsid_ui_translation_menu[i].nm_MutualExclude;
        vsid_ui_menu[j].nm_UserData = vsid_ui_translation_menu[i].nm_UserData;
        switch (vsid_ui_translation_menu[i].nm_Label) {
            case 0:
                vsid_ui_menu[j++].nm_Label = (STRPTR)NM_BARLABEL;
                break;
            default:
                vsid_ui_menu[j++].nm_Label = translate_text(vsid_ui_translation_menu[i].nm_Label);
                break;
        }
    }
    vsid_ui_menu[i].nm_Type = NM_END;
    vsid_ui_menu[i].nm_CommKey = NULL;
    vsid_ui_menu[i].nm_Flags = 0;
    vsid_ui_menu[i].nm_MutualExclude = 0L;
    vsid_ui_menu[i].nm_UserData = NULL;
    vsid_ui_menu[i].nm_Label = NULL;

    if (!(vsid_menu = CreateMenus(vsid_ui_menu, GTMN_FrontPen, 0L, TAG_DONE))) {
        return -1;
    }

    LayoutMenus(vsid_menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE);

    SetMenuStrip(vsid_window, vsid_menu);

    vsid_menu_update();

    UnlockPubScreen(NULL, pubscreen);

    return 0;
}
int ribi::ProjectRichelBilderbeekMenuDialog::ExecuteSpecific(const std::vector<std::string>& argv) noexcept
{
  const int argc = static_cast<int>(argv.size());

  if (argc == 1)
  {
    std::cout << GetHelp() << '\n';
    return 1;
  }
  const std::string s { argv[1] };
  if (s == "--status" || s == "-s")
  {
    ShowStatus();
    return 0;
  }
  if (s == "--program" || s == "-p")
  {
    for (const auto& m: CreateMenus())
    {
      assert(m);
      std::cout << m->GetProgram()->GetName() << '\n';
    }
    return 0;
  }
  //Find menu dialog and execute it with one argument less
  for (const auto& m: CreateMenus())
  {
    assert(m);
    if (s == m->GetProgram()->GetName() || s == m->GetAbout().GetFileTitle())
    {
      std::vector<std::string> sub_argv;
      std::copy(argv.begin() + 1,argv.end(),std::back_inserter(sub_argv));
      return m->Execute(sub_argv);
    }
  }
  std::cout << GetHelp() << '\n';
  return 1;
}
Ejemplo n.º 17
0
Window::Window()
    : m_bConnected(false)
{
    QIcon appIcon;
    appIcon.addFile(":Resources/icons/DICOM_Tool.png");
    this->setWindowIcon(appIcon);

    CreateToolbars();
    CreateCenterWidgets();
    CreateDocks();
    CreateMenus();

    setAcceptDrops(true);
    setWindowTitle(tr("DICOM Viewer"));
    resize(1600, 900);
}
Ejemplo n.º 18
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    strPathQssFile(":/QSS/QSS/StyleSheet.qss"),
    clrBKApp(QColor(205,215,230))
{
    ui->setupUi(this);

    CreateActions();
    CreateMenus();
    ui->mainToolBar->hide();
    InitMainWindow();
    InitStatusBar();

    BeautifyUI();
}
void ribi::ProjectRichelBilderbeekMenuDialog::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
  ProjectRichelBilderbeekMenuDialog d;
  //Create all menus
  for (const auto& m: CreateMenus())
  {
    assert(!m || !m->GetVersion().empty());
    assert(!m || !m->GetVersionHistory().empty());
    assert(!m || m->GetProgram());
  }
}
Ejemplo n.º 20
0
int main( int argc, char* argv[] )
{
    UIDesktop* desktop = UIDesktop::InitializeDesktop( true, true );
    UISubWindow *window = new UISubWindow( desktop, 6, 50, 10, 15, UIColors::BACKGROUND_TEXT_COLOR, false );
    window->WriteCentered( 1, " Text UI Demo " );
    window->WriteCentered( 3, " Copyright (c) 2007 WWIV Software Services. " );
    window->WriteCentered( 5, " All Rights Reserved. " );


    CreateMenus( desktop->GetMenuBar() );
    
    desktop->Paint();
    desktop->RunLoop();
    delete window;
    delete desktop;
	return 0;
}
Ejemplo n.º 21
0
MainFrame::MainFrame(void) : wxFrame(NULL, wxID_ANY, _("Omega Online Registry Editor")),
	m_fileHistory(8)
{
	wxIconBundle icon_bundle;
	icon_bundle.AddIcon(wxIcon(icon_large));
	icon_bundle.AddIcon(wxIcon(icon_small));

	SetIcons(icon_bundle);

	m_bKeys = false;
	m_bValues = false;
	m_bData = false;
	m_bMatchAll = false;
	m_bIgnoreCase = false;

	CreateChildWindows();
	CreateMenus();
}
Ejemplo n.º 22
0
static struct Menu *createViewerDisplayMenu(struct Screen *screen, const int previousItemEnabled, const int nextItemEnabled)
{
    /* Get some visual info required to properly generate the menu layout */
    APTR vi = GetVisualInfo(screen, TAG_END);
    
    if(vi == NULL)
    {
	fprintf(stderr, "Cannot obtain visual info!\n");
	return NULL;
    }
    else
    {
	/* Create a menu */
	
	struct NewMenu newMenu[] = {
	    {NM_TITLE, "Picture", 0, 0, 0, 0},
	    {NM_ITEM, "Open...", "O", 0, 0, 0},
	    {NM_ITEM, "Previous", "P", previousItemEnabled ? 0 : NM_ITEMDISABLED, 0, 0},
	    {NM_ITEM, "Next", "N", nextItemEnabled ? 0 : NM_ITEMDISABLED, 0, 0},
	    {NM_ITEM, "Hide Title", "S", CHECKIT | MENUTOGGLE, 0, 0},
	    {NM_ITEM, "Cycle", "C", CHECKIT | MENUTOGGLE, 0, 0},
	    {NM_ITEM, "Quit", "Q", 0, 0, 0},
	    {NM_END, NULL, 0, 0, 0, 0}
	};
	
	struct Menu *menu = CreateMenus(newMenu, GTMN_FullMenu, TRUE, TAG_END);
	
	if(menu != NULL)
	{
	    /* Properly layout the menu items */
	    if(!LayoutMenus(menu, vi, TAG_END))
	    {
		fprintf(stderr, "Cannot calculate menu layout!\n");
		FreeMenus(menu);
		menu = NULL;
	    }
	}
	
	FreeVisualInfo(vi); /* Cleanup */
	
	return menu; /* Return generated menu */
    }
}
JXExprEditor::JXExprEditor
	(
	const JVariableList*	varList,
	JXMenuBar*				menuBar,
	JXScrollbarSet*			scrollbarSet,
	JXContainer*			enclosure,
	const HSizingOption		hSizing,
	const VSizingOption		vSizing,
	const JCoordinate		x,
	const JCoordinate		y,
	const JCoordinate		w,
	const JCoordinate		h
	)
	:
	JXScrollableWidget(scrollbarSet, enclosure, hSizing, vSizing, x,y, w,h),
	JExprEditor(varList, JXScrollableWidget::GetFontManager(),
				JXScrollableWidget::GetColormap())
{
	JXExprEditorX();
	CreateMenus(menuBar, NULL);
}
Ejemplo n.º 24
0
//______________________________________________________________________________
YSPTView::YSPTView(QMenuBar *mb)
{
    //creates the view with a shared menubar

    // Sets up the subclassed QGraphicsView

    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);


    //Set-up the scene

    fPt = new YSPeriodicTable(this);
    setScene(fPt);

    //Set-up the view
    setSceneRect(fPt->sceneRect());

    //Use ScrollHand Drag Mode to enable Panning
    setDragMode(ScrollHandDrag);

    fMenuBar = mb;
    CreateActions();
    CreateMenus();
}
Ejemplo n.º 25
0
/******************************************************************
main:
******************************************************************/
int
main(int argc, char **argv)
{
    static Widget  MainWindow;
    XtAppContext   app_context;
    Widget         Frame1, RC1, Label1, DrawingArea1;
    Pixmap         pixmap;
    GC             gc;

    XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL);


    toplevel = XtOpenApplication(&app_context, "Test", NULL, 0,
                                 &argc, argv, NULL,
                                 sessionShellWidgetClass,
                                 NULL, 0);

    MainWindow = XtVaCreateManagedWidget("MainWindow1",
                                         xmMainWindowWidgetClass, toplevel,
                                         NULL);

    CreateMenus(MainWindow);

    RC1 = XtVaCreateManagedWidget("RC1", xmRowColumnWidgetClass,
                                  MainWindow, NULL);

    if (!argv[1]) {
        printf("usage: %s bitmap-file\n", *argv);
        exit(1);
    }

    /* Load bitmap given in argv[1] */
    pixmap = XmGetPixmap(XtScreen(toplevel), argv[1],
                         BlackPixelOfScreen(XtScreen(toplevel)),
                         WhitePixelOfScreen(XtScreen(toplevel)));

    if (pixmap == XmUNSPECIFIED_PIXMAP) {
        printf("can't create pixmap from %s\n", argv[1]);
        exit(1);
    }

    /* Now instantiate an XmLabel widget that displays pixmap. */
    Label1 = XtVaCreateManagedWidget("Label1",
                                     xmLabelWidgetClass, RC1,
                                     XmNlabelType,   XmPIXMAP,
                                     XmNlabelPixmap, pixmap,
                                     NULL);

    Frame1 = XtVaCreateManagedWidget("Frame1",
                                     xmFrameWidgetClass, RC1,
                                     XmNshadowThickness, 3,
                                     NULL);

    DrawingArea1 = XtVaCreateManagedWidget("DrawingArea1",
                                           xmDrawingAreaWidgetClass, Frame1,
                                           XmNwidth, 150,
                                           XmNheight, 150,
                                           XmNresizePolicy, XmRESIZE_NONE,
                                           NULL);
    XmeDropSink(DrawingArea1, NULL, 0);
    XtAddCallback(DrawingArea1, XmNdestinationCallback,
                  DestinationCallback, NULL);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app_context);

    return 0;    /* make compiler happy */
}
Ejemplo n.º 26
0
void EnviroFrame::CreateUI()
{
	VTLOG1("Frame window: creating menus and toolbars.\n");
	CreateMenus();

	// Create StatusBar
	m_pStatusBar = new MyStatusBar(this);
	SetStatusBar(m_pStatusBar);
	m_pStatusBar->Show();
	m_pStatusBar->UpdateText();
	PositionStatusBar();

#ifdef VTP_NVIDIA_PERFORMANCE_MONITORING
	// Stop crash in update toolbar
	m_pCameraDlg = NULL;
	m_pLocationDlg = NULL;
	m_pLODDlg = NULL;
	m_pPerformanceMonitorDlg = NULL;
#endif

	// An array of values to tell wxWidgets how to make our OpenGL context.
	std::vector<int> gl_attribs;
	gl_attribs.push_back(WX_GL_RGBA);			// Full color
	gl_attribs.push_back(WX_GL_DOUBLEBUFFER);
	gl_attribs.push_back(WX_GL_BUFFER_SIZE);	// 24-bit Z-buffer
	gl_attribs.push_back(24);
	gl_attribs.push_back(WX_GL_DEPTH_SIZE);
	gl_attribs.push_back(24);
	VTLOG("Anti-aliasing multisamples: %d\n", g_Options.m_iMultiSamples);
#if wxCHECK_VERSION(2, 9, 0)
	if (g_Options.m_iMultiSamples > 0)
	{
		gl_attribs.push_back(WX_GL_SAMPLE_BUFFERS);
		gl_attribs.push_back(1);
		gl_attribs.push_back(WX_GL_SAMPLES);
		gl_attribs.push_back(g_Options.m_iMultiSamples);
	}
#endif
	if (g_Options.m_bStereo && g_Options.m_iStereoMode == 1)	// 1 = Quad-buffer stereo
	{
		gl_attribs.push_back(WX_GL_STEREO);
	}
	// Zero terminates the array
	gl_attribs.push_back(0);

	VTLOG("Frame window: creating view canvas.\n");
	m_canvas = new EnviroCanvas(this, -1, wxPoint(0, 0), wxSize(-1, -1), 0,
		_T("vtGLCanvas"), &gl_attribs.front());

	// Show the frame
	VTLOG("Showing the main frame\n");
	Show(true);

	VTLOG("Constructing dialogs\n");
	m_pBuildingDlg = new BuildingDlg3d(this, -1, _("Building Properties"));
	m_pCameraDlg = new CameraDlg(this, -1, _("Camera-View"));
	m_pDistanceDlg = new DistanceDlg3d(this, -1, _("Distance"));
	m_pEphemDlg = new EphemDlg(this, -1, _("Ephemeris"));
	m_pFenceDlg = new LinearStructureDlg3d(this, -1, _("Linear Structures"));
	m_pInstanceDlg = new InstanceDlg3d(this, this, -1, _("Instances"),
		wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	m_pTagDlg = new TagDlg(this, -1, _("Tags"), wxDefaultPosition,
		wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	m_pTagDlg->SetSize(440,80);
	m_pLODDlg = new LODDlg(this, -1, _("Terrain LOD Info"), wxDefaultPosition,
		wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	// m_pLODDlg->Show();	// Enable this to see the LOD dialog immediately

	m_pPlantDlg = new PlantDlg(this, -1, _("Plants"));
	m_pPlantDlg->ShowOnlyAvailableSpecies(g_Options.m_bOnlyAvailableSpecies);
	m_pPlantDlg->SetLang(wxGetApp().GetLanguageCode());

	m_pLocationDlg = new LocationDlg(this, -1, _("Locations"),
			wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	m_pSceneGraphDlg = new SceneGraphDlg(this, -1, _("Scene Graph"),
			wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	m_pSceneGraphDlg->SetSize(450, 600);
	m_pTimeDlg = new TimeDlg(this, -1, _("Time"));
	m_pUtilDlg = new UtilDlg(this, -1, _("Utility Poles"));
	m_pScenarioSelectDialog = new ScenarioSelectDialog(this, -1, _("Scenarios"));
	m_pVehicleDlg = new VehicleDlg(this, -1, _("Vehicles"));
	m_pDriveDlg = new DriveDlg(this);
	m_pProfileDlg = NULL;
	#ifdef VTP_NVIDIA_PERFORMANCE_MONITORING
    m_pPerformanceMonitorDlg = new CPerformanceMonitorDialog(this, wxID_ANY, _("Performance Monitor"));
    #endif
	m_pVIADlg = new VIADlg(this);

#if wxVERSION_NUMBER < 2900		// before 2.9.0
	if (m_canvas)
		m_canvas->SetCurrent();
#else
	// Still need to do a "SetCurrent" here? It's more complicated now in wx 2.9.x,
	//  and it's probably already taken care of by GraphicsWindowWX?
#endif

	m_mgr.AddPane(m_canvas, wxAuiPaneInfo().
				  Name(wxT("canvas")).Caption(wxT("Canvas")).
				  CenterPane());
	m_mgr.Update();

	m_pLayerDlg = new LayerDlg(this, -1, _("Layers"), wxDefaultPosition,
		wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
	m_pLayerDlg->SetSize(500, -1);

	m_mgr.AddPane(m_pLayerDlg, wxAuiPaneInfo().
				  Name(_T("layers")).Caption(_("Layers")).
				  Left());
	m_mgr.Update();
}
Ejemplo n.º 27
0
void amiga_init (char *dir)
{
  if ((DefaultPubScreen = LockPubScreen (0)) == 0)
    exit (1);
  screen_ratio (DefaultPubScreen);

  char prog_name[256];
  static char font_name[MAXFONTPATH];
  char *font_desc, *name_ptr;
  static WORD pens[] =
  {-1};
  static struct TextAttr font =
  {NULL, 0, FS_NORMAL, 0};
  int window = 0;

  if (Icon == NULL)
  {
    if (GetProgramName (prog_name, 256))
      Icon = GetDiskObject (prog_name);
  }

  if (Icon)
  {
    if (FindToolType (Icon->do_ToolTypes, "WINDOW"))
      window = 1;
    if (font_desc = FindToolType (Icon->do_ToolTypes, "FONT"))
    {
      strcpy (font_name, font_desc);
      if (name_ptr = strrchr (font_name, '/'))
      {
	font.ta_Name = font_name;
	font.ta_YSize = atoi (name_ptr + 1);
	strcpy (name_ptr, ".font");
      }
    }
    if (font.ta_Name)
      Font = OpenDiskFont (&font);
  }
  if (Font == NULL)
  {
    font.ta_Name = "topaz.font";
    font.ta_YSize = 8;
    Font = OpenFont (&font);
  }

  if (window == 0)
  {
    if ((Screen = OpenScreenTags (0,
				  SA_Pens, pens,
				  SA_DisplayID, GetVPModeID (&DefaultPubScreen->ViewPort),
				  SA_Overscan, OSCAN_TEXT,
				  SA_Depth, 2,
				  SA_Type, CUSTOMSCREEN | AUTOSCROLL,
				  SA_Font, &font,
				  SA_Title, TitleBar, TAG_DONE)) == 0)
      exit (1);
  }

  if ((Window = OpenWindowTags (0,
				WA_Left, 0,
				WA_Top, Screen ? 2 : DefaultPubScreen->BarHeight + 1,
				WA_Width, Screen ? Screen->Width : ScreenWidth,
				WA_Height, Screen ? Screen->Height - 2 : ScreenHeight - DefaultPubScreen->BarHeight - 1,
				WA_SmartRefresh, 1,
				WA_NewLookMenus, 1,
				WA_AutoAdjust, 1,
				WA_Borderless, Screen ? 1 : 0,
				WA_Backdrop, Screen ? 1 : 0,
				WA_Activate, 1,
				WA_CloseGadget, Screen ? 0 : 1,
				WA_DragBar, Screen ? 0 : 1,
				WA_DepthGadget, Screen ? 0 : 1,
				WA_SizeGadget, Screen ? 0 : 1,
				WA_SizeBBottom, Screen ? 0 : 1,
				WA_Title, TitleBar,
				WA_ScreenTitle, TitleBar,
				WA_IDCMP, IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_CHANGEWINDOW,
				Screen ? WA_CustomScreen : WA_PubScreen, Screen ? Screen : DefaultPubScreen,
				TAG_DONE)) == 0)
    exit (1);

  ThisProcess = (struct Process *)FindTask(0);
  OldWindowPtr = ThisProcess->pr_WindowPtr;
  ThisProcess->pr_WindowPtr = Window;

  if ((Visual = GetVisualInfo (Window->WScreen, TAG_DONE)) == 0)
    exit (1);
  if ((Menus = CreateMenus (NewMenus, GTMN_NewLookMenus, TRUE, TAG_DONE)) == 0)
    exit (1);
  LayoutMenus (Menus, Visual, GTMN_NewLookMenus, TRUE, TAG_DONE);
  SetMenuStrip (Window, Menus);

  if ((GameReq = alloc_freq (dir)) == 0)
    exit (1);
  if ((SaveReq = alloc_freq (dir)) == 0)
    exit (1);
  if ((ScriptReq = alloc_freq (dir)) == 0)
    exit (1);

  RastPort = Window->RPort;
  SetDrMd (RastPort, JAM2);
  SetAPen (RastPort, 1);
  SetBPen (RastPort, 0);
  SetFont (RastPort, Font);
  DisplayHeight = ((Window->Height - Window->BorderTop - Window->BorderBottom) / RastPort->TxHeight) - 1;
  PreviousHeight = DisplayHeight;

  reset_cursor ();
}
Ejemplo n.º 28
0
void UpdateUserInterfaceForPolySamp()
{
    CreateMenus();
    CreateToolbars();
}
Ejemplo n.º 29
0
frmMain::frmMain(const wxString& title)
: pgFrame((wxFrame *)NULL, title)
{
    msgLevel=0;
    lastPluginUtility=NULL;
    pluginUtilityCount = 0;

    dlgName = wxT("frmMain");
    SetMinSize(wxSize(400,300));
    RestorePosition(50, 50, 750, 550, 600, 450);

    wxWindowBase::SetFont(settings->GetSystemFont());

    {
        wxLogInfo(wxT("Using fontmetrics %d/%d, %d Point"), GetCharWidth(), GetCharHeight(), GetFont().GetPointSize());
        wxLogInfo(wxT("Native Description '%s'"), GetFont().GetNativeFontInfoDesc().c_str());
        wxWindowDC dc(this);
        dc.SetFont(GetFont());

        wxCoord w, h, d, e;

        dc.GetTextExtent(wxT("M"), &w, &h, &d, &e);
        wxLogInfo(wxT("Draw size of 'M': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e);

        dc.GetTextExtent(wxT("g"), &w, &h, &d, &e);
        wxLogInfo(wxT("Draw size of 'g': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e);

        dc.GetTextExtent(wxT("Mg"), &w, &h, &d, &e);
        wxLogInfo(wxT("Draw size of 'Mg': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e);
    }

    // Current database
    denyCollapseItem=wxTreeItemId();
    currentObject = 0;

    appearanceFactory->SetIcons(this);

    // notify wxAUI which frame to use
    manager.SetManagedWindow(this);
    manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE);

    SetMinSize(wxSize(600, 450)); 

    // wxGTK needs this deferred
    pgaFactory::RealizeImages();

    CreateMenus();
    
    // Setup the object browser
    browser = new ctlTree(this, CTL_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER);
    browser->SetImageList(imageList);

    // Setup the listview
    listViews = new wxAuiNotebook(this, CTL_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON);

    // Switch to the generic list control. Native doesn't play well with
    // multi-row select on Mac.
#ifdef __WXMAC__
    wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true);
#endif

    properties = new ctlListView(listViews, CTL_PROPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);
    statistics = new ctlListView(listViews, CTL_STATVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);
	listViews->SetWindowStyle(wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_DEFAULT_STYLE);
    dependencies = new ctlListView(listViews, CTL_DEPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);
    dependents = new ctlListView(listViews, CTL_REFVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);

    // Switch back to the native list control.
#ifdef __WXMAC__
    wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false);
#endif

    listViews->AddPage(properties, _("Properties"));        // NBP_PROPERTIES
    listViews->AddPage(statistics, _("Statistics"));        // NBP_STATISTICS
    listViews->AddPage(dependencies, _("Dependencies"));    // NBP_DEPENDENCIES
    listViews->AddPage(dependents, _("Dependents"));        // NBP_DEPENDENTS

    properties->SetImageList(imageList, wxIMAGE_LIST_SMALL);
    statistics->SetImageList(imageList, wxIMAGE_LIST_SMALL);
    dependencies->SetImageList(imageList, wxIMAGE_LIST_SMALL);
    dependents->SetImageList(imageList, wxIMAGE_LIST_SMALL);

    properties->AddColumn(_("Properties"), 500);
    properties->InsertItem(0, _("No properties are available for the current selection"), PGICON_PROPERTY);

    wxColour background;
    background = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
    statistics->SetBackgroundColour(background);
    dependencies->SetBackgroundColour(background);
    dependents->SetBackgroundColour(background);

    // Setup the SQL pane
    sqlPane = new ctlSQLBox(this, CTL_SQLPANE, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_READONLY | wxTE_RICH2);
    sqlPane->SetBackgroundColour(background);

    // Setup menus
    pgaFactory::RegisterMenu(this, wxCommandEventHandler(frmMain::OnNew));
    menuFactories->RegisterMenu(this, wxCommandEventHandler(frmMain::OnAction));
    menuFactories->CheckMenu(0, menuBar, toolBar);

    // Kickstart wxAUI
    manager.AddPane(browser, wxAuiPaneInfo().Name(wxT("objectBrowser")).Caption(_("Object browser")).Left().MinSize(wxSize(100, 200)).BestSize(wxSize(200, 450)));
    manager.AddPane(listViews, wxAuiPaneInfo().Name(wxT("listViews")).Caption(_("Info pane")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200)));
    manager.AddPane(sqlPane, wxAuiPaneInfo().Name(wxT("sqlPane")).Caption(_("SQL pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200)));
    manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));

    // Now load the layout
    wxString perspective;
    settings->Read(wxT("frmMain/Perspective-") + wxString(FRMMAIN_PERSPECTIVE_VER), &perspective, FRMMAIN_DEFAULT_PERSPECTIVE);
    manager.LoadPerspective(perspective, true);

    // and reset the captions for the current language
    manager.GetPane(wxT("objectBrowser")).Caption(_("Object browser"));
    manager.GetPane(wxT("listViews")).Caption(_("Info pane"));
    manager.GetPane(wxT("sqlPane")).Caption(_("SQL pane"));
    manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));

    // Sync the View menu options
    viewMenu->Check(MNU_SQLPANE, manager.GetPane(wxT("sqlPane")).IsShown());
    viewMenu->Check(MNU_OBJECTBROWSER, manager.GetPane(wxT("objectBrowser")).IsShown());
    viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());

    // tell the manager to "commit" all the changes just made
    manager.Update();

    // Add the root node
    serversObj = new pgServerCollection(serverFactory.GetCollectionFactory());
    wxTreeItemId root = browser->AddRoot(_("Server Groups"), serversObj->GetIconId(), -1, serversObj);

    // Work around a bug in the generic tree control in wxWidgets, 
    // Per http://trac.wxwidgets.org/ticket/10085
    browser->SetItemText(root, _("Server Groups"));

    // Load servers
    RetrieveServers();

	browser->Expand(root);
    browser->SortChildren(root);
}
Ejemplo n.º 30
0
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch ( msg )
    {
		case WM_CREATE:
		{
			CreateMenus();

			// Set our menu bar.
			SetMenu( hWnd, g_hMenu );

			// Create our listview window.
			g_hWnd_list = CreateWindow( WC_LISTVIEW, NULL, LVS_REPORT | LVS_EDITLABELS | LVS_OWNERDRAWFIXED | WS_CHILDWINDOW | WS_VISIBLE, 0, 0, MIN_WIDTH, MIN_HEIGHT, hWnd, NULL, NULL, NULL );
			SendMessage( g_hWnd_list, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

			// Make pretty font.
			SendMessage( g_hWnd_list, WM_SETFONT, ( WPARAM )hFont, 0 );

			// Allow drag and drop for the listview.
			DragAcceptFiles( g_hWnd_list, TRUE );

			// Subclass our listview to receive WM_DROPFILES.
			ListViewProc = ( WNDPROC )GetWindowLong( g_hWnd_list, GWL_WNDPROC );
			SetWindowLong( g_hWnd_list, GWL_WNDPROC, ( LONG )ListViewSubProc );

			// Initialize our listview columns
			LVCOLUMNA lvc = { NULL }; 
			lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; 
			lvc.fmt = LVCFMT_CENTER;
			lvc.pszText = "#";
			lvc.cx = 34;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 0, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_LEFT;
			lvc.pszText = "Filename";
			lvc.cx = 135;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 1, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_RIGHT;
			lvc.pszText = "Cache Entry Offset";
			lvc.cx = 110;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 2, ( LPARAM )&lvc );

			lvc.pszText = "Cache Entry Size";
			lvc.cx = 95;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 3, ( LPARAM )&lvc );

			lvc.pszText = "Data Offset";
			lvc.cx = 88;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 4, ( LPARAM )&lvc );

			lvc.pszText = "Data Size";
			lvc.cx = 65;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 5, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_LEFT;
			lvc.pszText = "Data Checksum";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 6, ( LPARAM )&lvc );

			lvc.pszText = "Header Checksum";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 7, ( LPARAM )&lvc );

			lvc.pszText = "Cache Entry Hash";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 8, ( LPARAM )&lvc );

			lvc.pszText = "System";
			lvc.cx = 85;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 9, ( LPARAM )&lvc );

			lvc.pszText = "Location";
			lvc.cx = 200;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 10, ( LPARAM )&lvc );

			// Save our initial window position.
			GetWindowRect( hWnd, &last_pos );

			return 0;
		}
		break;

		case WM_KEYDOWN:
		{
			// We'll just give the listview control focus since it's handling our keypress events.
			SetFocus( g_hWnd_list );

			return 0;
		}
		break;

		case WM_MOVING:
		{
			POINT cur_pos;
			RECT wa;
			RECT *rc = ( RECT * )lParam;
			GetCursorPos( &cur_pos );
			OffsetRect( rc, cur_pos.x - ( rc->left + cx ), cur_pos.y - ( rc->top + cy ) );

			// Allow our main window to attach to the desktop edge.
			SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 );			
			if( is_close( rc->left, wa.left ) )				// Attach to left side of the desktop.
			{
				OffsetRect( rc, wa.left - rc->left, 0 );
			}
			else if ( is_close( wa.right, rc->right ) )		// Attach to right side of the desktop.
			{
				OffsetRect( rc, wa.right - rc->right, 0 );
			}

			if( is_close( rc->top, wa.top ) )				// Attach to top of the desktop.
			{
				OffsetRect( rc, 0, wa.top - rc->top );
			}
			else if ( is_close( wa.bottom, rc->bottom ) )	// Attach to bottom of the desktop.
			{
				OffsetRect( rc, 0, wa.bottom - rc->bottom );
			}

			// Allow our main window to attach to the image window.
			GetWindowRect( g_hWnd_image, &wa );
			if ( is_attached == false && IsWindowVisible( g_hWnd_image ) )
			{
				if( is_close( rc->right, wa.left ) )			// Attach to left side of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) )
					{
						OffsetRect( rc, wa.left - rc->right, 0 );
						is_attached = true;
					}
				}
				else if ( is_close( wa.right, rc->left ) )		// Attach to right side of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) )
					{
						OffsetRect( rc, wa.right - rc->left, 0 );
						is_attached = true;
					}
				}

				if( is_close( rc->bottom, wa.top ) )			// Attach to top of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) )
					{
						OffsetRect( rc, 0, wa.top - rc->bottom );
						is_attached = true;
					}
				}
				else if ( is_close( wa.bottom, rc->top ) )		// Attach to bottom of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) )
					{
						OffsetRect( rc, 0, wa.bottom - rc->top );
						is_attached = true;
					}
				}
			}

			// See if our image window is visible
			if ( IsWindowVisible( g_hWnd_image ) )
			{
				// If it's attached, then move it in proportion to our main window.
				if ( is_attached == true )
				{
					// If our main window attached itself to the image window, then we'll skip moving the image window.
					if ( skip_main == true )
					{
						// Moves the image window with the main window.
						MoveWindow( g_hWnd_image, wa.left + ( rc->left - last_pos.left ), wa.top + ( rc->top - last_pos.top ), wa.right - wa.left, wa.bottom - wa.top, FALSE );
					}
					else
					{
						// This causes the image window to snap to the main window. Kinda like a magnet. This is how they work by the way.
						MoveWindow( hWnd, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, FALSE );
					}
					
					skip_main = true;
				}
			}

			// Save our last position.
			last_pos.bottom = rc->bottom;
			last_pos.left = rc->left;
			last_pos.right = rc->right;
			last_pos.top = rc->top;

			return TRUE;
		}
		break;

		case WM_ENTERSIZEMOVE:
		{
			//Get the current position of our window before it gets moved.
			POINT cur_pos;
			RECT rc;
			GetWindowRect( hWnd, &rc );
			GetCursorPos( &cur_pos );
			cx = cur_pos.x - rc.left;
			cy = cur_pos.y - rc.top;

			return 0;
		}
		break;

		case WM_SIZE:
		{
			// If our window changes size, assume we aren't attached anymore.
			is_attached = false;
			skip_main = false;

			RECT rc;
			GetClientRect( hWnd, &rc );

			// Allow our listview to resize in proportion to the main window.
			HDWP hdwp = BeginDeferWindowPos( 1 );
			DeferWindowPos( hdwp, g_hWnd_list, HWND_TOP, 0, 0, rc.right, rc.bottom, 0 );
			EndDeferWindowPos( hdwp );

			return 0;
		}
		break;

		case WM_MEASUREITEM:
		{
			// Set the row height of the list view.
			if ( ( ( LPMEASUREITEMSTRUCT )lParam )->CtlType = ODT_LISTVIEW )
			{
				( ( LPMEASUREITEMSTRUCT )lParam )->itemHeight = row_height;
			}
			return TRUE;
		}
		break;

		case WM_GETMINMAXINFO:
		{
			// Set the minimum dimensions that the window can be sized to.
			( ( MINMAXINFO * )lParam )->ptMinTrackSize.x = MIN_WIDTH;
			( ( MINMAXINFO * )lParam )->ptMinTrackSize.y = MIN_HEIGHT;
			
			return 0;
		}
		break;

		case WM_CHANGE_CURSOR:
		{
			// SetCursor must be called from the window thread.
			if ( wParam == TRUE )
			{
				wait_cursor = LoadCursor( NULL, IDC_APPSTARTING );	// Arrow + hourglass.
				SetCursor( wait_cursor );
			}
			else
			{
				SetCursor( LoadCursor( NULL, IDC_ARROW ) );	// Default arrow.
				wait_cursor = NULL;
			}
		}
		break;

		case WM_SETCURSOR:
		{
			if ( wait_cursor != NULL )
			{
				SetCursor( wait_cursor );	// Keep setting our cursor if it reverts back to the default.
				return TRUE;
			}

			DefWindowProc( hWnd, msg, wParam, lParam );
			return FALSE;
		}
		break;

		case WM_COMMAND:
		{
			// Check to see if our command is a menu item.
			if ( HIWORD( wParam ) == 0 )
			{
				// Get the id of the menu item.
				switch( LOWORD( wParam ) )
				{
					case MENU_OPEN:
					{
						pathinfo *pi = ( pathinfo * )malloc( sizeof( pathinfo ) );
						pi->filepath = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH * MAX_PATH );
						wmemset( pi->filepath, 0, MAX_PATH * MAX_PATH );
						OPENFILENAME ofn = { NULL };
						ofn.lStructSize = sizeof( OPENFILENAME );
						ofn.lpstrFilter = L"Thumbcache Database Files (*.db)\0*.db\0Iconcache Database Files (*.db)\0*.db\0All Files (*.*)\0*.*\0";
						ofn.lpstrFile = pi->filepath;
						ofn.nMaxFile = MAX_PATH * MAX_PATH;
						ofn.lpstrTitle = L"Open a Thumbcache Database file";
						ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_READONLY;
						ofn.hwndOwner = hWnd;

						// Display the Open File dialog box
						if ( GetOpenFileName( &ofn ) )
						{
							pi->offset = ofn.nFileOffset;
							pi->output_path = NULL;
							pi->type = 0;
							cmd_line = 0;

							// pi will be freed in the thread.
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &read_thumbcache, ( void * )pi, 0, NULL ) );
						}
						else
						{
							free( pi->filepath );
							free( pi );
						}
					}
					break;

					case MENU_SAVE_ALL:
					case MENU_SAVE_SEL:
					{
						// Open a browse for folder dialog box.
						BROWSEINFO bi = { 0 };
						bi.hwndOwner = hWnd;
						if ( LOWORD( wParam ) == MENU_SAVE_ALL )
						{
							bi.lpszTitle = L"Select a location to save all the file(s).";
						}
						else
						{
							bi.lpszTitle = L"Select a location to save the selected file(s).";
						}
						bi.ulFlags = BIF_EDITBOX | BIF_VALIDATE;

						LPITEMIDLIST lpiidl = SHBrowseForFolder( &bi );
						if ( lpiidl )
						{
							wchar_t *save_directory = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH );
							wmemset( save_directory, 0, MAX_PATH );

							// Get the directory path from the id list.
							SHGetPathFromIDList( lpiidl, save_directory );
							CoTaskMemFree( lpiidl );

							save_param *save_type = ( save_param * )malloc( sizeof( save_param ) );	// Freed in the save_items thread.
							save_type->type = 0;	// Save files to filepath. The directory should exist so no need to build it.
							save_type->save_all = ( LOWORD( wParam ) == MENU_SAVE_ALL ? true : false );
							save_type->filepath = save_directory;

							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_items, ( void * )save_type, 0, NULL ) );
						}
					}
					break;

					case MENU_EXPORT:
					{
						wchar_t *file_path = ( wchar_t * )malloc( sizeof ( wchar_t ) * MAX_PATH );
						wmemset( file_path, 0, MAX_PATH );

						OPENFILENAME ofn = { 0 };
						ofn.lStructSize = sizeof( OPENFILENAME );
						ofn.hwndOwner = hWnd;
						ofn.lpstrFilter = L"CSV (Comma delimited) (*.csv)\0*.csv\0";
						ofn.lpstrDefExt = L"csv";
						ofn.lpstrTitle = L"Export list to a CSV (comma-separated values) file";
						ofn.lpstrFile = file_path;
						ofn.nMaxFile = MAX_PATH;
						ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_READONLY;

						if ( GetSaveFileName( &ofn ) )
						{
							// file_path is freed in the save_csv thread.
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_csv, ( void * )file_path, 0, NULL ) );
						}
						else
						{
							free( file_path );
						}
					}
					break;

					case MENU_HIDE_BLANK:
					{
						hide_blank_entries = !hide_blank_entries;

						// Put a check next to the menu item if we choose to hide blank entries. Remove it if we don't.
						CheckMenuItem( g_hMenu, MENU_HIDE_BLANK, ( hide_blank_entries ? MF_CHECKED : MF_UNCHECKED ) );

						// Hide if we have items in the list and show if we have blank entries.
						if ( ( g_be == NULL && SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) || g_be != NULL )
						{
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &show_hide_items, ( void * )NULL, 0, NULL ) );
						}
					}
					break;

					case MENU_CHECKSUMS:
					{
						// Go through each item in the list and verify the header and data checksums.
						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &verify_checksums, ( void * )NULL, 0, NULL ) );
					}
					break;

					case MENU_SCAN:
					{
						SendMessage( g_hWnd_scan, WM_PROPAGATE, 0, 0 );
					}
					break;

					case MENU_REMOVE_SEL:
					{
						// Hide the image window since the selected item will be deleted.
						if ( IsWindowVisible( g_hWnd_image ) )
						{
							ShowWindow( g_hWnd_image, SW_HIDE );
						}

						is_attached = false;
						skip_main = false;

						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &remove_items, ( void * )NULL, 0, NULL ) );
					}
					break;

					case MENU_COPY_SEL:
					{
						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &copy_items, ( void * )0, 0, NULL ) );
					}
					break;

					case MENU_SELECT_ALL:
					{
						// Set the state of all items to selected.
						LVITEM lvi = { NULL };
						lvi.mask = LVIF_STATE;
						lvi.state = LVIS_SELECTED;
						lvi.stateMask = LVIS_SELECTED;
						SendMessage( g_hWnd_list, LVM_SETITEMSTATE, -1, ( LPARAM )&lvi );

						UpdateMenus( UM_ENABLE );
					}
					break;

					case MENU_INFO:
					{
						LVITEM lvi = { NULL };
						lvi.mask = LVIF_PARAM;
						lvi.iItem = SendMessage( g_hWnd_list, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED );

						if ( lvi.iItem != -1 )
						{
							SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi );

							SendMessage( g_hWnd_info, WM_PROPAGATE, 0, lvi.lParam );
						}
					}
					break;

					case MENU_ABOUT:
					{
						MessageBoxA( hWnd, "Thumbcache Viewer is made free under the GPLv3 license.\r\n\r\nVersion 1.0.3.1\r\n\r\nCopyright \xA9 2011-2015 Eric Kutcher", PROGRAM_CAPTION_A, MB_APPLMODAL | MB_ICONINFORMATION );
					}
					break;

					case MENU_EXIT:
					{
						SendMessage( hWnd, WM_CLOSE, 0, 0 );
					}
					break;
				}
			}
			return 0;
		}
		break;

		case WM_NOTIFY:
		{
			// Get our listview codes.
			switch ( ( ( LPNMHDR )lParam )->code )
			{
				case LVN_KEYDOWN:
				{
					NMLVKEYDOWN *nmlvkd = ( NMLVKEYDOWN * )lParam;

					// Make sure the control key is down and that we're not already in a worker thread. Prevents threads from queuing in case the user falls asleep on their keyboard.
					if ( GetKeyState( VK_CONTROL ) & 0x8000 && in_thread == false )
					{
						// Determine which key was pressed.
						switch ( nmlvkd->wVKey )
						{
							case 'A':	// Select all items if Ctrl + A is down and there are items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SELECT_ALL, 0 );
								}
							}
							break;

							case 'O':	// Open the file dialog box if Ctrl + O is down.
							{
								SendMessage( hWnd, WM_COMMAND, MENU_OPEN, 0 );
							}
							break;

							case 'H':	// Hide blank entries if Ctrl + H is down.
							{
								SendMessage( hWnd, WM_COMMAND, MENU_HIDE_BLANK, 0 );
							}
							break;

							case 'V':	// Verify checksums.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_CHECKSUMS, 0 );
								}
							}
							break;

							case 'M':	// Map entry hash values to local files.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SCAN, 0 );
								}
							}
							break;

							case 'R':	// Remove selected items if Ctrl + R is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_REMOVE_SEL, 0 );
								}
							}
							break;

							case 'C':	// Copy selected items if Ctrl + C is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_COPY_SEL, 0 );
								}
							}
							break;

							case 'S':	// Save all/selected items if Ctrl + S or Ctrl + Shift + S is down and there are items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 && !( GetKeyState( VK_SHIFT ) & 0x8000 ) )	// Shift not down.
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SAVE_ALL, 0 );
								}
								else if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 && ( GetKeyState( VK_SHIFT ) & 0x8000 ) ) // Shift down.
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SAVE_SEL, 0 );
								}
							}
							break;

							case 'I':	// View extended information if Ctrl + I is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 );
								}
							}
							break;

							case 'E':	// Export list to a CSV (comma-separated values) file.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_EXPORT, 0 );
								}
							}
							break;
						}
					}
				}
				break;

				case LVN_COLUMNCLICK:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					// Change the format of the items in the column if Ctrl is held while clicking the column.
					if ( GetKeyState( VK_CONTROL ) & 0x8000 )
					{
						switch ( nmlv->iSubItem )
						{
							case 2:	// Change the cache entry offset column info.
							{
								is_kbytes_c_offset = !is_kbytes_c_offset;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 3:	// Change the cache entry size column info.
							{
								is_kbytes_c_size = !is_kbytes_c_size;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 4:	// Change the data offset column info.
							{
								is_kbytes_d_offset = !is_kbytes_d_offset;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 5:	// Change the data size column info.
							{
								is_kbytes_d_size = !is_kbytes_d_size;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 6:	// Change the data checksum column info.
							{
								is_dc_lower = !is_dc_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;
							
							case 7:	// Change the header checksum column info.
							{
								is_hc_lower = !is_hc_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 8:	// Change the entry hash column info.
							{
								is_eh_lower = !is_eh_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;
						}
					}
					else	// Normal column click. Sort the items in the column.
					{
						LVCOLUMN lvc = { NULL };
						lvc.mask = LVCF_FMT;
						SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );
						
						if ( HDF_SORTUP & lvc.fmt )	// Column is sorted upward.
						{
							// Sort down
							lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) | HDF_SORTDOWN;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, ( WPARAM )nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
						else if ( HDF_SORTDOWN & lvc.fmt )	// Column is sorted downward.
						{
							// Sort up
							lvc.fmt = lvc.fmt & ( ~HDF_SORTDOWN ) | HDF_SORTUP;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem + NUM_COLUMNS, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
						else	// Column has no sorting set.
						{
							// Remove the sort format for all columns.
							for ( int i = 0; i < NUM_COLUMNS; i++ )
							{
								// Get the current format
								SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, i, ( LPARAM )&lvc );
								// Remove sort up and sort down
								lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) & ( ~HDF_SORTDOWN );
								SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, i, ( LPARAM )&lvc );
							}

							// Read current the format from the clicked column
							SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );
							// Sort down to start.
							lvc.fmt = lvc.fmt | HDF_SORTDOWN;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
					}
				}
				break;

				case NM_RCLICK:
				{
					// Show our edit context menu as a popup.
					POINT p;
					GetCursorPos( &p ) ;
					TrackPopupMenu( g_hMenuSub_context, 0, p.x, p.y, 0, hWnd, NULL );
				}
				break;

				case NM_DBLCLK:
				{
					NMITEMACTIVATE *nmitem = ( NMITEMACTIVATE *)lParam;

					if ( nmitem->iItem != -1 )
					{
						SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 );
					}
				}
				break;

				case LVN_DELETEITEM:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					// Item count will be 1 since the item hasn't yet been deleted.
					if ( SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) == 1 )
					{
						// Disable the menus that require at least one item in the list.
						UpdateMenus( UM_DISABLE_OVERRIDE );
					}
				}
				break;

				case LVN_ITEMCHANGED:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					if ( in_thread == false )
					{
						UpdateMenus( UM_ENABLE );
					}

					// Only load images that are selected and in focus.
					if ( nmlv->uNewState != ( LVIS_FOCUSED | LVIS_SELECTED ) )
					{
						break;
					}
					
					// Retrieve the lParam value from the selected listview item.
					LVITEM lvi = { NULL };
					lvi.mask = LVIF_PARAM;
					lvi.iItem = nmlv->iItem;
					SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi );

					fileinfo *fi = ( fileinfo * )lvi.lParam;
					if ( fi == NULL || ( fi != NULL && fi->si == NULL ) )
					{
						break;
					}

					// Create a buffer to read in our new bitmap.
					char *current_image = ( char * )malloc( sizeof( char ) * fi->size );

					// Attempt to open a file for reading.
					HANDLE hFile = CreateFile( fi->si->dbpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
					if ( hFile != INVALID_HANDLE_VALUE )
					{
						DWORD read = 0;
						// Set our file pointer to the beginning of the database file.
						SetFilePointer( hFile, fi->data_offset, 0, FILE_BEGIN );
						// Read the entire image into memory.
						ReadFile( hFile, current_image, fi->size, &read, NULL );
						CloseHandle( hFile );

						// If gdi_image exists, then delete it.
						if ( gdi_image != NULL )
						{
							delete gdi_image;
							gdi_image = NULL;
						}

						// Create a stream to store our buffer and then store the stream into a GDI+ image object.
						ULONG written = 0;
						IStream *is = NULL;
						CreateStreamOnHGlobal( NULL, TRUE, &is );
						is->Write( current_image, read, &written );	// Only write what we've read.
						gdi_image = new Gdiplus::Image( is );
						is->Release();

						if ( !IsWindowVisible( g_hWnd_image ) )
						{
							// Move our image window next to the main window on its right side if it's the first time we're showing the image window.
							if ( first_show == false )
							{
								SetWindowPos( g_hWnd_image, HWND_TOPMOST, last_pos.right, last_pos.top, MIN_HEIGHT, MIN_HEIGHT, SWP_NOACTIVATE );
								first_show = true;
							}

							// This is done to keep both windows on top of other windows.
							// Set the image window position on top of all windows except topmost windows, but don't set focus to it.
							SetWindowPos( g_hWnd_image, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
							// Set our main window on top of the image window.
							SetWindowPos( hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
							// The image window is on top of everything (except the main window), set it back to non-topmost.
							SetWindowPos( g_hWnd_image, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
						}

						// Set our image window's icon to match the file extension.
						if ( fi->flag & FIF_TYPE_BMP )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_bmp );
						}
						else if ( fi->flag & FIF_TYPE_JPG )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_jpg );
						}
						else if ( fi->flag & FIF_TYPE_PNG )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_png );
						}
						else
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, NULL );
						}

						// Set the image window's new title.
						wchar_t new_title[ MAX_PATH + 30 ] = { 0 };
						swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", ( fi->filename != NULL ? fi->filename : L"" ), gdi_image->GetWidth(), gdi_image->GetHeight() );
						SetWindowText( g_hWnd_image, new_title );

						// See if our image window is minimized and set the rectangle to its old size if it is.
						RECT rc;
						if ( IsIconic( g_hWnd_image ) == TRUE )
						{
							rc = last_dim;
						}
						else // Otherwise, get the current size.
						{
							GetClientRect( g_hWnd_image, &rc );
						}

						old_pos.x = old_pos.y = 0;
						drag_rect.x = drag_rect.y = 0;

						// Center the image.
						drag_rect.x = ( ( long )gdi_image->GetWidth() - rc.right ) / 2;
						drag_rect.y = ( ( long )gdi_image->GetHeight() - rc.bottom ) / 2;

						scale = 1.0f;	// Reset the image scale.

						// Force our window to repaint itself.
						InvalidateRect( g_hWnd_image, NULL, TRUE );
					}

					// Free our image buffer.
					free( current_image );
				}
				break;

				case LVN_BEGINLABELEDIT:
				{
					NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam;
					
					// If no item is being edited, then cancel the edit.
					if ( pdi->item.iItem == -1 )
					{
						return TRUE;
					}

					// Get the current list item text from its lParam.
					LVITEM lvi = { NULL };
					lvi.iItem = pdi->item.iItem;
					lvi.iSubItem = 1;
					lvi.mask = LVIF_PARAM;
					SendMessage( pdi->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi );

					// Save our current fileinfo.
					current_fileinfo = ( fileinfo * )lvi.lParam;
					if ( current_fileinfo == NULL )
					{
						return TRUE;
					}
					
					// Get the bounding box of the Filename column we're editing.
					current_edit_pos.top = 1;
					current_edit_pos.left = LVIR_BOUNDS;
					SendMessage( pdi->hdr.hwndFrom, LVM_GETSUBITEMRECT, pdi->item.iItem, ( LPARAM )&current_edit_pos );
					
					// Get the edit control that the listview creates.
					g_hWnd_edit = ( HWND )SendMessage( pdi->hdr.hwndFrom, LVM_GETEDITCONTROL, 0, 0 );

					// Subclass our edit window to modify its position.
					EditProc = ( WNDPROC )GetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC );
					SetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC, ( LONG )EditSubProc );

					// Set our edit control's text to the list item's text.
					SetWindowText( g_hWnd_edit, current_fileinfo->filename );

					// Get the length of the filename without the extension.
					int ext_len = wcslen( current_fileinfo->filename );
					while ( ext_len != 0 && current_fileinfo->filename[ --ext_len ] != L'.' );

					// Select all the text except the file extension (if ext_len = 0, then everything is selected)
					SendMessage( g_hWnd_edit, EM_SETSEL, 0, ext_len );

					// Allow the edit to proceed.
					return FALSE;
				}
				break;

				case LVN_ENDLABELEDIT:
				{
					NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam;

					// Prevent the edit if there's no text.
					if ( pdi->item.pszText == NULL )
					{
						return FALSE;
					}
					// Prevent the edit if the text length is 0.
					unsigned int length = wcslen( pdi->item.pszText );
					if ( length == 0 )
					{
						return FALSE;
					}

					// Free the old filename.
					free( current_fileinfo->filename );
					// Create a new filename based on the editbox's text.
					wchar_t *filename = ( wchar_t * )malloc( sizeof( wchar_t ) * ( length + 1 ) );
					wmemset( filename, 0, length + 1 );
					wcscpy_s( filename, length + 1, pdi->item.pszText );

					// Modify our listview item's fileinfo lParam value.
					current_fileinfo->filename = filename;

					// Set the image window's new title.
					wchar_t new_title[ MAX_PATH + 30 ] = { 0 };
					swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", filename, gdi_image->GetWidth(), gdi_image->GetHeight() );
					SetWindowText( g_hWnd_image, new_title );

					return TRUE;
				}
				break;

			}
			return FALSE;
		}
		break;

		case WM_DRAWITEM:
		{
			DRAWITEMSTRUCT *dis = ( DRAWITEMSTRUCT * )lParam;
      
			// The item we want to draw is our listview.
			if ( dis->CtlType == ODT_LISTVIEW && dis->itemData != NULL )
			{
				fileinfo *fi = ( fileinfo * )dis->itemData;
				if ( fi->si == NULL )
				{
					return TRUE;
				}

				// Alternate item color's background.
				if ( dis->itemID % 2 )	// Even rows will have a light grey background.
				{
					HBRUSH color = CreateSolidBrush( ( COLORREF )RGB( 0xF7, 0xF7, 0xF7 ) );
					FillRect( dis->hDC, &dis->rcItem, color );
					DeleteObject( color );
				}

				// Set the selected item's color.
				bool selected = false;
				if ( dis->itemState & ( ODS_FOCUS || ODS_SELECTED ) )
				{
					if ( skip_draw == true )
					{
						return TRUE;	// Don't draw selected items because their lParam values are being deleted.
					}

					HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) );
					FillRect( dis->hDC, &dis->rcItem, color );
					DeleteObject( color );
					selected = true;
				}

				wchar_t tbuf[ MAX_PATH ];
				wchar_t *buf = tbuf;

				// This is the full size of the row.
				RECT last_rc;

				// This will keep track of the current colunn's left position.
				int last_left = 0;

				// Adjust the alignment position of the text.
				int RIGHT_COLUMNS = 0;

				LVCOLUMN lvc = { 0 };
				lvc.mask = LVCF_WIDTH;

				// Loop through all the columns
				for ( int i = 0; i < NUM_COLUMNS; ++i )
				{
					RIGHT_COLUMNS = 0;

					// Save the appropriate text in our buffer for the current column.
					switch ( i )
					{
						case 0:
						{
							swprintf_s( buf, MAX_PATH, L"%d", dis->itemID + 1 );
						}
						break;

						case 1:
						{
							buf = ( fi->filename != NULL ? fi->filename : L"" );
						}
						break;

						case 2:
						{
							buf = tbuf;	// Reset the buffer pointer.
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the offset (db location) in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_c_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_c_offset == true ? fi->header_offset : fi->header_offset / 1024 ) );
						}
						break;

						case 3:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							unsigned int cache_entry_size = fi->size + ( fi->data_offset - fi->header_offset );

							// Depending on our toggle, output the size in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_c_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_c_size == true ? cache_entry_size / 1024 : cache_entry_size ) );
						}
						break;

						case 4:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the offset (db location) in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_d_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_d_offset == true ? fi->data_offset : fi->data_offset / 1024 ) );
						}
						break;

						case 5:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the size in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_d_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_d_size == true ? fi->size / 1024 : fi->size ) );
						}
						break;

						case 6:
						{
							// Output the hex string in either lowercase or uppercase.
							int out = swprintf_s( buf, MAX_PATH, ( is_dc_lower == true ? L"%016llx" : L"%016llX" ), fi->data_checksum );

							if ( fi->v_data_checksum != fi->data_checksum )
							{
								swprintf_s( buf + out, MAX_PATH - out, ( is_dc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_data_checksum );
							}
						}
						break;

						case 7:
						{
							// Output the hex string in either lowercase or uppercase.
							int out = swprintf_s( buf, MAX_PATH, ( is_hc_lower == true ? L"%016llx" : L"%016llX" ), fi->header_checksum );

							if ( fi->v_header_checksum != fi->header_checksum )
							{
								swprintf_s( buf + out, MAX_PATH - out, ( is_hc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_header_checksum );
							}
						}
						break;

						case 8:
						{
							// Output the hex string in either lowercase or uppercase.
							swprintf_s( buf, MAX_PATH, ( is_eh_lower == true ? L"%016llx" : L"%016llX" ), fi->entry_hash );
						}
						break;

						case 9:
						{
							switch ( fi->si->system )
							{
								case WINDOWS_VISTA:
								{
									buf = L"Windows Vista";
								}
								break;

								case WINDOWS_7:
								{
									buf = L"Windows 7";
								}
								break;

								case WINDOWS_8:
								case WINDOWS_8v2:
								case WINDOWS_8v3:
								{
									buf = L"Windows 8";
								}
								break;

								case WINDOWS_8_1:
								{
									buf = L"Windows 8.1";
								}
								break;

								case WINDOWS_10:
								{
									buf = L"Windows 10";
								}
								break;

								default:
								{
									buf = L"Unknown";
								}
								break;
							}
						}
						break;

						case 10:
						{
							buf = fi->si->dbpath;
						}
						break;
					}

					// Get the dimensions of the listview column
					SendMessage( dis->hwndItem, LVM_GETCOLUMN, i, ( LPARAM )&lvc );

					last_rc = dis->rcItem;

					// This will adjust the text to fit nicely into the rectangle.
					last_rc.left = 5 + last_left;
					last_rc.right = lvc.cx + last_left - 5;

					// Save the last left position of our column.
					last_left += lvc.cx;

					// Save the height and width of this region.
					int width = last_rc.right - last_rc.left;
					if ( width <= 0 )
					{
						continue;
					}

					int height = last_rc.bottom - last_rc.top;

					// Normal text position.
					RECT rc;
					rc.top = 0;
					rc.left = 0;
					rc.right = width;
					rc.bottom = height;

					// Shadow text position.
					//RECT rc2 = rc;
					//rc2.left += 1;
					//rc2.top += 1;
					//rc2.right += 1;
					//rc2.bottom += 1;

					// Create and save a bitmap in memory to paint to.
					HDC hdcMem = CreateCompatibleDC( dis->hDC );
					HBITMAP hbm = CreateCompatibleBitmap( dis->hDC, width, height );
					HBITMAP ohbm = ( HBITMAP )SelectObject( hdcMem, hbm );
					DeleteObject( ohbm );
					DeleteObject( hbm );
					HFONT ohf = ( HFONT )SelectObject( hdcMem, hFont );
					DeleteObject( ohf );

					// Transparent background for text.
					SetBkMode( hdcMem, TRANSPARENT );

					// Draw selected text
					if ( selected == true )
					{
						// Fill the background.
						HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) );
						FillRect( hdcMem, &rc, color );
						DeleteObject( color );

						// Shadow color - black.
						//SetTextColor( hdcMem, RGB( 0x00, 0x00, 0x00 ) );
						//DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						// White text.
						SetTextColor( hdcMem, RGB( 0xFF, 0xFF, 0xFF ) );
						DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCCOPY );
					}
					else	// Draw normal text.
					{
						// Fill the background.
						HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_WINDOW ) );
						FillRect( hdcMem, &rc, color );
						DeleteObject( color );

						// Shadow color - light grey.
						//SetTextColor( hdcMem, RGB( 0xE0, 0xE0, 0xE0 ) );
						//DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						// Show red text if our checksums don't match, green text for entries with extended info, and black text for everything else.
						COLORREF text_color = RGB( 0x00, 0x00, 0x00 );
						if ( i == 1 && fi->ei != NULL )
						{
							text_color = RGB( 0x00, 0x80, 0x00 );
						}
						else if ( ( i == 6 && ( fi->v_data_checksum != fi->data_checksum ) ) ||
								  ( i == 7 && ( fi->v_header_checksum != fi->header_checksum ) ) )
						{
							text_color = RGB( 0xFF, 0x00, 0x00 );
						}
						SetTextColor( hdcMem, text_color );
						DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCAND );
					}

					// Delete our back buffer.
					DeleteDC( hdcMem );
				}
			}
			return TRUE;
		}
		break;

		case WM_CLOSE:
		{
			// Prevent the possibility of running additional processes.
			EnableWindow( hWnd, FALSE );
			ShowWindow( hWnd, SW_HIDE );
			EnableWindow( g_hWnd_image, FALSE );
			ShowWindow( g_hWnd_image, SW_HIDE );
			EnableWindow( g_hWnd_info, FALSE );
			ShowWindow( g_hWnd_info, SW_HIDE );
			EnableWindow( g_hWnd_property, FALSE );
			ShowWindow( g_hWnd_property, SW_HIDE );
			EnableWindow( g_hWnd_scan, FALSE );
			ShowWindow( g_hWnd_scan, SW_HIDE );

			// If we're in a secondary thread, then kill it (cleanly) and wait for it to exit.
			if ( in_thread == true )
			{
				CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &cleanup, ( void * )NULL, 0, NULL ) );
			}
			else	// Otherwise, destroy the window normally.
			{
				g_kill_thread = true;
				DestroyWindow( hWnd );
			}

			return 0;
		}
		break;

		case WM_DESTROY_ALT:
		{
			DestroyWindow( hWnd );
		}
		break;

		case WM_DESTROY:
		{
			// Get the number of items in the listview.
			int item_count = SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 );

			LVITEM lvi = { NULL };
			lvi.mask = LVIF_PARAM;

			fileinfo *fi = NULL;

			// Go through each item, and free their lParam values. current_fileinfo will get deleted here.
			for ( int i = 0; i < item_count; ++i )
			{
				lvi.iItem = i;
				SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi );

				fi = ( fileinfo * )lvi.lParam;
				if ( fi != NULL )
				{
					if ( fi->si != NULL )
					{
						--( fi->si->count );

						// Remove our shared information from the linked list if there's no more items for this database.
						if ( fi->si->count == 0 )
						{
							free( fi->si );
						}
					}

					cleanup_extended_info( fi->ei );

					// First free the filename pointer.
					free( fi->filename );
					// Then free the fileinfo structure.
					free( fi );
				}
			}

			// Delete our image object.
			if ( gdi_image != NULL )
			{
				delete gdi_image;
			}

			cleanup_blank_entries();

			// Since these aren't owned by a window, we need to destroy them.
			DestroyMenu( g_hMenuSub_context );
			DestroyMenu( g_hMenuSub_ei_context );

			PostQuitMessage( 0 );
			return 0;
		}
		break;

		default:
		{
			return DefWindowProc( hWnd, msg, wParam, lParam );
		}
		break;
	}
	return TRUE;
}