/*
* Progman.cpp
* Copyright (c) 2009 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
// SOL++2000
// 2000.03.20
// 2009/11/06 Modified to stop the Program Scanner Thread
#include <sol\ApplicationView.h>
#include <sol\Thread.h>
#include <sol\PopupView.h>
#include <sol\ListView.h>
#include <sol\ImageList.h>
#include <sol\Stdio.h>
#include "Resource.h"
#define WM_LISTUP (WM_USER+200)
// class ProgramScanner
namespace SOL {
class ProgramScanner :public Thread {
private:
ImageList& imageList;
ListView& listView;
bool cancel;
View* application;
private:
static const UINT WM_SOL_THREAD_CANCEL = (WM_USER+2009);
public:
ProgramScanner(View* parent, ListView& listv, ImageList& image)
:application(parent),
listView(listv),
imageList(image)
{
Args ar;
ar.set(XmNwidth, 300);
ar.set(XmNheight, 50);
}
public:
void run()
{
cancel = false;
TCHAR path[10];
TCHAR drive[10];
DWORD d = ::GetLogicalDrives();
for(int i = 0; i<26; i++) {
dispatchMessage();
Sleep(10);
if (cancel == true) {
break;
}
if(d & 1) {
_stprintf_s(path, SizeOf(path), _T("%c:"), 'A'+i);
_stprintf_s(drive, SizeOf(drive), _T("%c:\\"), 'A'+i);
UINT driveType = GetDriveType(drive);
if (driveType == DRIVE_FIXED) {
find(path);
}
}
d = d >> 1;
}
}
private:
void dispatchMessage()
{
MSG msg;
while(
PeekMessage (&msg,NULL,0,0,PM_REMOVE)) {
Sleep(10);
if (msg.message == WM_SOL_THREAD_CANCEL) {
this->cancel = true;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
private:
void find(TCHAR* dir)
{
String xdir = &dir[1];
if (xdir.startsWithIgnoreCase(_T(":\\$Recycle.Bin"))) {
//2009/11/06 Skip Recyle.Bin folder
return;
}
//dispatchMessage();
if (this->cancel) {
return;
}
WIN32_FIND_DATA data;
TCHAR* buffer = new TCHAR[_MAX_PATH*2];
_stprintf_s(buffer, _MAX_PATH*2, _T("%s\\*"), dir);
HANDLE fFile= ::FindFirstFile(buffer, &data);
application->setText(buffer);
if(fFile != INVALID_HANDLE_VALUE) {
do {
dispatchMessage();
//Sleep(10);
if (this->cancel == true) {
break;
}
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (strcmp(_T("."), data.cFileName) != 0 &&
strcmp(_T(".."), data.cFileName) != 0) {
TCHAR* subDir = new TCHAR[_MAX_PATH*2];
_stprintf_s(subDir, _MAX_PATH*2, _T("%s\\%s"), dir, data.cFileName);
find(subDir);
delete [] subDir;
}
} else {
CharLower(data.cFileName);
//Listup only *.exe files.
const TCHAR* p = strstr(data.cFileName, _T(".exe"));
if (p) {
addToListView(dir, data.cFileName);
}
}
} while(::FindNextFile(fFile, &data));
::FindClose(fFile);
}
delete [] buffer;
}
public:
void stop()
{
cancel = true;
post(WM_SOL_THREAD_CANCEL, 0, 0);
}
private:
void addToListView(TCHAR* dir, TCHAR* fileName)
{
// Extract an icon.
TCHAR fullpath[_MAX_PATH];
_stprintf_s(fullpath, SizeOf(fullpath), _T("%s\\%s"), dir, fileName);
HINSTANCE hInst = GetModuleHandle(NULL);//Application::getInstance();
int number = (int)ExtractIcon(hInst, fullpath, -1);
for (int i = 0; i<number; i++) {
dispatchMessage();
if (cancel) {
break;
}
HICON hicon = ExtractIcon(hInst, fullpath, i);
if(hicon) {
LV_ITEM item;
memset(&item, 0, sizeof(LV_ITEM));
// If it has an icon, add it ot the imageList.
item.mask = LVIF_TEXT|LVIF_IMAGE;
int id = imageList.addIcon(hicon);
item.iImage = id;
item.pszText = fullpath; //fileName;
item.cchTextMax = _MAX_PATH;
listView.insertItem(&item);
//2009/11/06 Only list up the first icon
break;
}
}
}
};
// ProgramManager
class ProgramManager :public ApplicationView {
private:
ProgramScanner* scanner;
ImageList imageList;
ListView listView;
int lastChangedItem;
public:
// * Constructor
ProgramManager(Application& applet, const TCHAR* name, Args& args)
:ApplicationView(applet, name, args),
imageList(32, 32, ILC_COLOR24|ILC_MASK, 0, 5)
{
Args ar;
//ar.set(XmNstyle, (ulong)WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_ICON);
ar.set(XmNstyle, (ulong)WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_SORTASCENDING|LVS_REPORT);
listView.create(this, NULL, ar);
listView.setImageList(&imageList, LVSIL_SMALL);
listView.setImageList(&imageList, LVSIL_NORMAL);
ListViewColumn item[1] = {
{_T("Filename"), 0, 500}
} ;
listView.setColumn(item, 1);
// Add the listView to the default LayoutManager.
add(listView);
listView.addCallback(XmNdoubleClickCallback, this,
(Callback)&ProgramManager::launch, NULL);
listView.addCallback(XmNitemChangedCallback, this,
(Callback)&ProgramManager::itemChanged, NULL);
ar.reset();
ar.set(XmNwidth, 300);
ar.set(XmNheight, 50);
lastChangedItem = -1;
// Add a menucallback.
addCallback(XmNmenuCallback, IDM_RESUME, this,
(Callback)&ProgramManager::resume, null);
// Add a menucallback.
addCallback(XmNmenuCallback, IDM_SUSPEND, this,
(Callback)&ProgramManager::suspend, null);
// Add a menucallback.
addCallback(XmNmenuCallback, IDM_EXIT, this,
(Callback)&ProgramManager::exit, null);
addEventHandler(WM_LISTUP, this,
(Handler)&ProgramManager::listup, NULL);
scanner = NULL;
post(WM_LISTUP, 0, 0);
restorePlacement();
}
public:
~ProgramManager()
{
//stopScanner();
if (scanner) {
delete scanner;
}
}
public:
void suspend(Action& action)
{
if (scanner) {
//Suspend the Scanner Thread
scanner->suspend();
}
}
private:
void stopScanner()
{
if (scanner) {
//Do resume the scanner thread, even if it's running.
scanner->resume();
scanner->stop();
scanner->wait();
}
}
public:
void resume(Action& action)
{
if (scanner) {
//Resume the Scanner Thread.
scanner->resume();
}
}
private:
long close(Event& event)
{
stopScanner();
imageList.clear();
savePlacement();
return defaultProc(event);
}
private:
long listup(Event& event)
{
listView.deleteAllItems();
scanner = new ProgramScanner(this, listView, imageList);
scanner ->start();
return 0L;
}
private:
void launch(Action& action)
{
if(lastChangedItem >= 0) {
TCHAR text[_MAX_PATH];
listView.getItemText(lastChangedItem,
0, text, SizeOf(text));
ShellExecute(NULL, _T("open"), text, NULL, NULL, SW_SHOW);
}
}
private:
void itemChanged(Action& action)
{
Event& event = action.getEvent();
NM_LISTVIEW* nmlistv = (NM_LISTVIEW*)event.getLParam();
lastChangedItem = nmlistv->iItem;
if(lastChangedItem >= 0) {
TCHAR text[_MAX_PATH];
listView.getItemText(lastChangedItem,
0, text, sizeof(text));
TCHAR title[_MAX_PATH];
_stprintf_s(title, SizeOf(title), _T("ProgramManager - %s "), text);
setText(title);
}
}
};
}
// ProgramManager Main
void Main(int argc, TCHAR** argv)
{
const String appClass = "ProgramManager";
try {
Application applet(appClass, argc, argv);
Args args;
ProgramManager programManager(applet, appClass, args);
programManager.realize();
applet.run();
} catch (...) {
}
}
|