CListBox hotlight tracking - clistbox

I used DrawItem () to redraw CListBox. ods_hotlight does not work in win7/win8.
How can I do this CListBox hotlight tracking?

OK ,I solved this now .... ,Code posted below :
extern "C" WINUSERAPI BOOL WINAPI TrackMouseEvent (LPTRACKMOUSEEVENT lpEventTrack);
void CListBoxCS::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = 1;
TrackMouseEvent (&tme);
BOOL bOut = TRUE;
short index;
index = (short) ItemFromPoint (point,bOut);
if (FALSE == bOut) {
if (m_ihot != index) {
m_ihot = index;
//printf ("index = %d \n",m_ihot);
Invalidate (FALSE);
}
} else {
//printf ( "out \n" );
}
}
void CListBoxCS::OnMouseLeave (void)
{
//printf ( "mouse leave \n" );
m_ihot = -1;
}
void CListBoxCS::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// some judgements here .....
// some preparations
// hot light code ...
if ((act & ODA_SELECT) || (act & ODA_DRAWENTIRE)) {
if (lpDIS->itemState & ODS_SELECTED) {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (209, 232, 255)));
} else {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (230, 230, 230)));
}
if (m_ihot == lpDrawItemStruct->itemID) {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (229, 243, 251)));
}
}
// something U like to do ....
}

Related

Why won't image 1 move to the right?

I'm very new to coding and was wondering how I could make this image move to the right. I added all of my code so that it would be a bit more understandable for what's going on. The moveRight command will not actually move the png to the right which is why I need help fixing and understanding why it won't work. If someone can please help me it would be greatly appreciated.
PImage background, backgroundGameState1, headbasketballbackground, player1, player2;
boolean moveRight, moveLeft;
int canvasSizeX= 1000;
int canvasSizeY = 600;
int mainBackgroundX = 1000;
int mainBackgroundY = 600;
int gameState1 = 1;
int player1X = 100;
int player1Y = 200;
int player2X = 100;
int player2Y = 200;
int backgroundGameState1X= 1000;
int backgroundGameState1Y=600;
int time;
int player1MovmentX = 100;
int player2MovmentX = 700;
void setup() {
//size of canvas
size(1000, 600);
//Loaded images and called them, also made sure to resize them in order to match the canvas size or to make program more asthetically pleasing
background = loadImage("headbasketballbackground.png");
background.resize(mainBackgroundX, mainBackgroundY);
backgroundGameState1 = loadImage("backgroundgamestate1.png");
backgroundGameState1.resize(backgroundGameState1X, backgroundGameState1Y);
player1 = loadImage("steph.png");
player1.resize(player1X, player1Y);
player2 = loadImage("paul.png");
player2.resize(player2X, player2Y);
time=millis();
}
void draw() {
if (gameState1 == 1) {
background(backgroundGameState1);
if (millis() > time + 1000) {
text("Click On Space To Enter The Game!", 100, 100);
textSize(50);
// delay(3000);
}
drawGameState1();
}
if (gameState1 == 2) {
background(background);
image(player1, player1MovmentX, 300);
image(player2, player2MovmentX, 300);
}
// if (gameState2 == 3) {
// text("Congrats you won!");
//}
}
void drawGameState1() {
}
void drawGameState2() {
drawPlayer1Movment();
}
void drawPlayer1Movment(){
if(moveRight){
player1MovmentX += 25;
}
}
void drawGameState3() {
}
void keyPressed() {
if (gameState1 == 1) {
if (keyCode == 32) {
gameState1 = 2;
}
}
else if(gameState1 == 2){
if(keyCode == RIGHT){
moveRight = true;
}
}
}
void keyReleased(){
if(keyCode == RIGHT){
moveRight = false;
}
}
I don't think you ever called drawPlayer1Movement(). Add it to keyPressed() and player1 should move to the right when you hit the right arrow.
void keyPressed() {
if (gameState1 == 1) {
if (keyCode == 32) {
gameState1 = 2;
}
} else if (gameState1 == 2) {
if (keyCode == RIGHT) {
moveRight = true;
drawPlayer1Movment();
}
}
}

I am building win32 application which empties the clipboard when a screenshot is took.But the image is not emptying

I am building a Win32 application which empties the clipboard when a screenshot is taken. But the image is not emptying.
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) //callback function
{
TCHAR str[255];
if (!hWnd){
return TRUE; // Not a window
}
if (IsWindowVisible(hWnd)) {
if ((GetWindowLongPtr(hWnd, GWL_STYLE) & WS_ICONIC)) {
return TRUE; // Window is minimized
}
if (GetWindowText(hWnd, str, 255)) {
// LOGGER->info("In Screenshots detection, windows text: {}",wstringToString(str));
if (_wcsicmp(str, _T("Program Manager"))){
TCHAR proc_name[1024];
HANDLE proc_hnd = NULL;
DWORD proc_id;
int flag;
GetWindowThreadProcessId(hWnd, &proc_id);
proc_hnd = OpenProcess(PROCESS_ALL_ACCESS, TRUE, proc_id);
if (proc_hnd != NULL) {
flag = GetProcessImageFileName(proc_hnd, proc_name, 1024);
if (flag != 0) {
if (wcsstr(proc_name, _T("chrome.exe"))) {
if (OpenClipboard(NULL)) {
//if (OpenClipboard(0&)) {
EmptyClipboard(); //emptyng the clipboard
// SetClipboardData(CF_BITMAP, "");
CloseClipboard(); //closing the clipboard
LOGGER->info("Screen capture on chrome is blocked!");
}
else {
LOGGER->error("Error in denying scrn capture on chrome!,Error: {}",GetLastError());
}
}
}
}
return 1;
}
else {
return TRUE;
}
}
else {
return TRUE; // No window title
}
}
return TRUE;
}

How to get windows folder display order by C + +

I need to get the pictures in the windows folder and sort them according to the order in which they are displayed. Now there is a method to traverse the entire folder display items through the handle by getting the folder window handle. However, this method has a drawback: it can't get the order of the unopened folder, because there is no open file and no window handle.
Qt is used.
Please forgive my grammatical mistakes.
//Find out the current folder window according to the mouse click position
HWND findOpenFileWindow(const QString& path)
{
Sleep(3 * 1000);
POINT pNow = { 0, 0 };
if (!GetCursorPos(&pNow))
return NULL;
TCHAR szClass[255] = {0};
HWND pMouseChooseHandle = WindowFromPoint(pNow);
HWND pParent = ::GetParent(pMouseChooseHandle);
GetClassName(pParent, szClass, 255);
if (_tcscmp(szClass, L"SHELLDLL_DefView") == 0 || _tcscmp(szClass, L"NSEViewClass") == 0 )
{
bool bQingDisk = _tcscmp(szClass, L"NSEViewClass") == 0;
pParent = ::GetParent(pParent);
GetClassName(pParent, szClass, 255);
if (_tcscmp(szClass, L"WorkerW"))
{
pParent = pMouseChooseHandle;
for (int i = 0; i < 6; i++)
{
if(pParent != NULL)
pParent = ::GetParent(pParent);
}
HWND pChild = ::GetWindow(pParent, GW_CHILD);
GetClassName(pChild, szClass, 255);
while (pChild != NULL)
{
GetClassName(pChild, szClass, 255);
if (_tcscmp(szClass, TEXT("ShellTabWindowClass")) == 0)
{
pParent = pChild;
break;
}
pChild = ::GetNextWindow(pChild, GW_HWNDNEXT);
}
TCHAR exploreWndName[MAX_PATH] = {0};
::GetWindowText(pParent, exploreWndName, MAX_PATH);
if(QFileInfo(path).fileName() == QString().fromWCharArray(exploreWndName))
return pParent;
}
}
return NULL;
}
//Traverse window display items, get them
QStringList listNormalFolderFile( const QString& path, const QStringList& filter )
{
HWND folderWnd = findOpenFileWindow(path);
HWND hwnd;
IDispatch *pDispatch;
CComPtr<IShellWindows> pShellWindows;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pShellWindows));
if (FAILED(hr))
{
CoUninitialize();
return QStringList();
}
LONG lCount = 0;
pShellWindows->get_Count(&lCount);
QStringList fileList;
for (LONG i = 0; i < lCount; i++)
{
CComPtr<IShellBrowser> pShellBrowser;
VARIANT var;
var.vt = VT_I4;
var.lVal = i;
if(SUCCEEDED(pShellWindows->Item(var, &pDispatch)))
{
if(SUCCEEDED(IUnknown_QueryService(pDispatch, SID_STopLevelBrowser, IID_PPV_ARGS(&pShellBrowser))))
{
if (SUCCEEDED(IUnknown_GetWindow(pShellBrowser, &hwnd)))
{
TCHAR szBuf[256];
GetWindowText(hwnd, szBuf, sizeof(szBuf) / sizeof(TCHAR));
if(QFileInfo(path).fileName() != QString().fromWCharArray(szBuf))
continue;
CComPtr<IShellView> pShellView;
if(FAILED(pShellBrowser->QueryActiveShellView(&pShellView)))
continue;
CComPtr<IFolderView> pFv = NULL;
/*
do something here
*/
CComPtr<IPersistFolder2 > pFolder;
if( FAILED(pFv->GetFolder(IID_IPersistFolder2, (void**) &pFolder)))
continue;
LPITEMIDLIST pidl = nullptr;
if( SUCCEEDED(pFolder->GetCurFolder(&pidl)))
{
wchar_t cPath[32767];
if( ::SHGetPathFromIDList(pidl, cPath))
{
QString filePath;
QFileInfo fileInfo(filePath.fromWCharArray(cPath));
if(fileInfo.absoluteFilePath() == QFileInfo(path).absoluteFilePath())
{
if(folderWnd == NULL || folderWnd == hwnd)
{
fileList = listFileInBrowser(pShellBrowser, filter);
break;
}
}
}
}
}
}
}
}
CoUninitialize();
return fileList;

Printing the wrong text and getting results randomly

Here's my code, where lastLine checks the last of the file:
import java.util.Random;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public String lastLine( File file ) {
RandomAccessFile fileHandler = null;
try {
fileHandler = new RandomAccessFile( file, "r" );
long fileLength = fileHandler.length() - 1;
StringBuilder sb = new StringBuilder();
for(long filePointer = fileLength; filePointer != -1; filePointer--){
fileHandler.seek( filePointer );
int readByte = fileHandler.readByte();
if( readByte == 0xA ) {
if( filePointer == fileLength ) {
continue;
}
break;
} else if( readByte == 0xD ) {
if( filePointer == fileLength - 1 ) {
continue;
}
break;
}
sb.append( ( char ) readByte );
}
String lastLine = sb.reverse().toString();
return lastLine;
} catch( java.io.FileNotFoundException e ) {
e.printStackTrace();
return null;
} catch( java.io.IOException e ) {
e.printStackTrace();
return null;
} finally {
if (fileHandler != null )
try {
fileHandler.close();
} catch (IOException e) {
/* ignore */
}
}
}
File file = new File("lines.txt");
String last = lastLine(file);
String previous = null;
float r = random(0,255);
float g = random(0, 255);
float b = random(0, 255);
public void settings() {
size(500, 500);
}
public void setup() {
frameRate(60);
stroke(155, 0, 0);
textAlign(CENTER, CENTER);
textSize(30);
background(r+(random(0,100)), g+(random(0,100)), b+(random(0,100)));
}
void draw() {
previous = lastLine(file);
if (last.equals(previous)) {
last = lastLine(file);
}
if (!last.equals(previous)) {
if (last.indexOf("w") != -1) {
text("there is a w", 255, 255);
fill(r, g, b);
}
else {
text("there is not a w", 255, 255);
}
fill(50);
last = lastLine(file);
}
}
So whenever the last line of the file has been changed, the text printed on screen should change to "there is a w" or "there is not a w" depending on whether or not there is a w in the last line. However, I seem to be getting results randomly. For example, when the last string of the file contains a "w," sometimes I get "there is not a w" printed on the screen. I've also gotten "there is a w" for when there is no w in the string.
What did I do wrong?
Your code is doing some strange things: why are you reading in the file 3 separate times in the draw() function? Why are you reading in the file one byte at a time?
Instead of trying to go through your code, here is an example that seems to do what you want:
String previous;
void draw() {
String current = lastLine();
if (!current.equals(previous)) {
background(random(255), random(255), random(255));
if (current.contains("w")) {
text("YES W", 0, 50);
} else {
text("NO W", 0, 50);
}
}
previous = current;
}
public String lastLine() {
String lines[] = loadStrings("list.txt");
if(lines.length == 0){
return "";
}
return lines[lines.length-1];
}
Also note that if you're not going to be deploying as JavaScript, you might want to use Java's file watch service instead of reading in the file every frame.

Developing with Firefox SDK with IDE (Visual Studio 2013 maybe)

I started developing a Firefox add-on, however I could not find any IDE specifically for Firefox. For most part it doesn't really matter because I can just open Javascript files and edit them (I use VS2013 and Web Essentials (I think)).
Up to this point everything is acceptable, but when I have to use cmd every time to run this plugin and then read console logs from cmd, it becomes a nightmare.
So my is - is there some way to launch, develop and log Firefox plugin just like any code in Visual Studio 2013? Other IDEs are welcome too.
Well I think it would be possible to create Visual Studio add-on, but it just too much work. However, I managed to partly integrate Firefox add-on creation into VS2013 with c++ code. It redirects cmd window so that means, that you'll output from cmd in "Output" window while debugging.
I'm leaving complete code with steps in case someone else needs this (C++11 is required):
Create Win32 C++ project (not cmd one).
Paste code (below) into cpp file.
Change YOUR_EXTENSION_NAME to your add-on name.
Run code once, it should throw message box with info where to put Add-on SDK.
Copy SDK files to that folder.
Run code again and exit (you may exit however you want, it should terminate remaining windows).
Now there are 3 options for file (.js, .css, etc.) linking:
Create files manually in SDK folder and add them manually to project.
Create files via VS2013 menu and then uncomment and modify, add, delete lines in do while loop.
Create files via VS2013 menu, but choose SDK folders.
Code:
#include <windows.h>
#include <tchar.h>
#include <thread>
#include <chrono>
#include <typeinfo>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")
// Timer code start
/*
//
//Credit goes to James Daughtry for this piece of code
//
*/
class Timer {
typedef std::chrono::high_resolution_clock high_resolution_clock;
typedef std::chrono::milliseconds milliseconds;
public:
Timer(bool run = false)
{
if (run) Reset();
}
void Reset()
{
_start = high_resolution_clock::now();
}
milliseconds Elapsed() const
{
return std::chrono::duration_cast<milliseconds>(high_resolution_clock::now() - _start);
}
private:
high_resolution_clock::time_point _start;
};
// Timer code end
// Cmd redirection code start
/*
//
//Credit goes to some guys from StackOverflow for directions and Randor from CodeProject for base code
//
*/
struct _JOBWRAPPER
{
HANDLE hJob;
_JOBWRAPPER() : hJob(NULL) {}
~_JOBWRAPPER() { if (this->hJob != NULL) CloseHandle(hJob); }
operator HANDLE() const { return this->hJob; }
}hJob;
typedef void(*TextOutFunction)(LPCSTR);
struct _THREADARGUMENTS
{
HANDLE hOutRead;
clock_t stTimeout;
LPCSTR pchBreakText;
TextOutFunction Function;
bool bGotInfo;
_THREADARGUMENTS() : bGotInfo(false), hOutRead(NULL), stTimeout(NULL), pchBreakText(nullptr), Function(nullptr) {}
};
void ReadCMDThread(_THREADARGUMENTS* Arguments)
{
if (Arguments->hOutRead != NULL)
{
UINT CheckForAnyResponseOnLoop = 5, CurrentLoop = 0;
clock_t ScanInterval = 50;
DWORD dwAvailable = 0;
DWORD bytesRead = 0;
CHAR szOut[4096] = { 0 };
if (Arguments->stTimeout == 0)
{
while (true)
{
CurrentLoop++;
PeekNamedPipe(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, &dwAvailable, NULL);
if (0 != bytesRead)
{
if (ReadFile(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, NULL))
Arguments->bGotInfo = true;
Arguments->Function(szOut);
if (Arguments->pchBreakText != nullptr && Arguments->pchBreakText != "" && strstr(szOut, Arguments->pchBreakText) != nullptr)
break;
memset(szOut, '\0', sizeof(char) * 4096);
}
if (CheckForAnyResponseOnLoop == CurrentLoop && Arguments->pchBreakText == "")
break;
std::this_thread::sleep_for((std::chrono::milliseconds)ScanInterval);
}
}
else
{
Timer timer(true);
while (timer.Elapsed() < (std::chrono::milliseconds)Arguments->stTimeout)
{
CurrentLoop++;
PeekNamedPipe(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, &dwAvailable, NULL);
if (0 != bytesRead)
{
if (ReadFile(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, NULL))
Arguments->bGotInfo = true;
Arguments->Function(szOut);
timer.Reset();
if (Arguments->pchBreakText != nullptr && Arguments->pchBreakText != "" && strstr(szOut, Arguments->pchBreakText) != nullptr)
break;
memset(szOut, '\0', sizeof(char) * 4096);
}
if (CheckForAnyResponseOnLoop == CurrentLoop && Arguments->pchBreakText == "")
break;
std::this_thread::sleep_for((std::chrono::milliseconds)ScanInterval);
}
}
}
}
class CMDREDIRECTION{
private:
HANDLE hInRead, hInWrite, hOutRead, hOutWrite;
PROCESS_INFORMATION pi;
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
TextOutFunction CustomFunction;
public:
CMDREDIRECTION(TextOutFunction Function) : hInRead(NULL), hInWrite(NULL), hOutRead(NULL),
hOutWrite(NULL), CustomFunction(Function) {}
~CMDREDIRECTION(){
if (hInRead != NULL)
CloseHandle(hInRead);
if (hInWrite != NULL)
CloseHandle(hInWrite);
if (hOutRead != NULL)
CloseHandle(hOutRead);
if (hOutWrite != NULL)
CloseHandle(hOutWrite);
}
DWORD WriteToCmd(LPSTR pchString, bool PressEnter = false)
{
DWORD dwWritten = 0;
size_t GivenStringLength = strlen(pchString);
LPSTR TemporaryString = pchString;
bool bSuccess = false;
if (GivenStringLength != 0)
{
if (PressEnter)
{
size_t StringSize = GivenStringLength + 2;
TemporaryString = new CHAR[StringSize];
for (size_t i = 0; i < GivenStringLength; i++)
TemporaryString[i] = pchString[i];
TemporaryString[StringSize - 2] = '\n';
TemporaryString[StringSize - 1] = '\0';
bSuccess = (WriteFile(hInWrite, TemporaryString, strlen(TemporaryString), &dwWritten, NULL) && dwWritten);
delete[] TemporaryString;
}
else
bSuccess = (WriteFile(hInWrite, TemporaryString, strlen(TemporaryString), &dwWritten, NULL) && dwWritten);
}
return bSuccess;
}
bool GetAnswer(clock_t stTimeout, LPCSTR pchBreakText)
{
_THREADARGUMENTS Arguments;
Arguments.hOutRead = hOutRead;
Arguments.pchBreakText = pchBreakText;
Arguments.stTimeout = stTimeout;
Arguments.Function = CustomFunction;
std::thread CMDWatcher(ReadCMDThread, &Arguments);
CMDWatcher.join();
return Arguments.bGotInfo;
}
bool WriteToCmdAndWaitForAnswer(LPSTR pchString, clock_t stTimeout, LPCSTR pchBreakText, bool PressEnter = false)
{
if (WriteToCmd(pchString, PressEnter))
{
return (GetAnswer(stTimeout, pchBreakText));
}
else
{
return false;
}
}
bool Start()
{
if (hJob.hJob == NULL)
{
hJob.hJob = CreateJobObject(NULL, NULL);
if (hJob.hJob != NULL)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (!SetInformationJobObject((HANDLE)hJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
return false;
}
}
else
{
return false;
}
}
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
CreatePipe(&hInRead, &hInWrite, &sa, 0);
CreatePipe(&hOutRead, &hOutWrite, &sa, 0);
ZeroMemory(&si, sizeof(si));
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = hOutWrite;
si.hStdError = hOutWrite;
si.hStdInput = hInRead;
si.wShowWindow = SW_HIDE;
TCHAR Path[MAX_PATH] = { 0 };
GetSystemDirectory(Path, MAX_PATH);
_tcscat_s(Path, TEXT("\\cmd.exe"));
if (CreateProcess(Path, NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
BOOL bResult = AssignProcessToJobObject(hJob, pi.hProcess);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return (bResult != 0);
}
else
{
return false;
}
}
};
// Cmd redirection code end
// TString code start
#ifdef UNICODE
#define TCat TCatW
#define TString _TString<WCHAR>
#else
#define TCat TCatA
#define TString _TString<CHAR>
#endif
struct AnyString
{
PVOID String;
bool bWide;
AnyString(LPSTR String)
{
this->String = String;
bWide = false;
}
AnyString(LPWSTR String)
{
this->String = String;
bWide = true;
}
operator LPSTR() { return (LPSTR)String; }
operator LPSTR() const { return (LPSTR)String; }
operator LPWSTR() { return (LPWSTR)String; }
operator LPWSTR() const { return (LPWSTR)String; }
};
template<class T>
class _TString
{
friend void SeAnyString(LPSTR String, _TString<CHAR> &TempString);
T *String;
size_t size;
void free()
{
if (String != nullptr && size != 0)
{
delete[] String;
String = nullptr;
size = 0;
}
}
_TString<CHAR> ToCHAR(LPWSTR wch)
{
_TString<CHAR> TempString;
LPSTR Buffer = nullptr;
size_t size = wcslen(wch),
realsize = size + 1;
if (size != 0)
{
Buffer = new CHAR[realsize];
wcstombs_s(nullptr, Buffer, realsize, wch, size);
TempString.SetAllocatedString(Buffer, size);
}
return TempString;
}
_TString<WCHAR> ToWCHAR(LPSTR ch)
{
_TString<WCHAR> TempString;
LPWSTR Buffer = nullptr;
size_t size = strlen(ch),
realsize = size + 1;
if (size != 0)
{
Buffer = new WCHAR[realsize];
mbstowcs_s(nullptr, Buffer, realsize, ch, size);
TempString.SetAllocatedString(Buffer, size);
}
return TempString;
}
public:
_TString(T *String)
{
free();
if (typeid(T) == typeid(CHAR))
{
size = strlen(String);
if (size != 0)
{
this->String = new T[size + 1];
for (size_t i = 0; i < size; i++)
this->String[i] = String[i];
this->String[size] = '\0';
}
}
else if (typeid(T) == typeid(WCHAR))
{
size = wcslen(String);
if (size != 0)
{
this->String = new T[size + 1];
for (size_t i = 0; i < size; i++)
this->String[i] = String[i];
this->String[size] = L'\0';
}
}
}
_TString() : String(nullptr), size(0) {}
~_TString() { free(); }
_TString(_TString&& OldTempStr)
{
this->String = OldTempStr.String;
this->size = OldTempStr.size;
OldTempStr.size = 0;
OldTempStr.String = nullptr;
}
_TString& operator=(_TString&& OldTempStr)
{
this->String = OldTempStr.String;
this->size = OldTempStr.size;
OldTempStr.size = 0;
OldTempStr.String = nullptr;
return *this;
}
operator T*() const { return String; }
operator T*() { return String; }
T& operator[] (size_t i) { return String[i]; }
void SetAllocatedString(T *String, size_t size)
{
free();
this->String = String;
this->size = size;
}
void join(LPWSTR StringToJoin)
{
join(AnyString(StringToJoin));
}
void join(LPSTR StringToJoin)
{
join(AnyString(StringToJoin));
}
void join(AnyString StringToJoin)
{
if (typeid(T) == typeid(CHAR))
{
size_t length = 0;
_TString<CHAR> TempString;
LPSTR StringLiteral = nullptr;
if (StringToJoin.bWide)
{
TempString = ToCHAR(StringToJoin);
StringLiteral = TempString;
}
else
{
StringLiteral = StringToJoin;
}
if (StringLiteral != nullptr)
length = strlen(StringLiteral);
if (length != 0)
{
size_t newsize = size + length, realsize = newsize + 1;
T *Buffer = new T[realsize];
for (size_t i = 0; i < size; i++)
Buffer[i] = String[i];
for (size_t i = size, j = 0; i < newsize; i++, j++)
Buffer[i] = StringLiteral[j];
Buffer[newsize] = '\0';
free();
size = newsize;
String = Buffer;
}
}
else if (typeid(T) == typeid(WCHAR))
{
size_t length = 0;
_TString<WCHAR> TempString;
LPWSTR StringLiteral = nullptr;
if (StringToJoin.bWide)
{
StringLiteral = StringToJoin;
}
else
{
TempString = ToWCHAR(StringToJoin);
StringLiteral = TempString;
}
if (StringLiteral != nullptr)
length = wcslen(StringLiteral);
if (length != 0)
{
size_t newsize = size + length, realsize = newsize + 1;
T *Buffer = new T[realsize];
for (size_t i = 0; i < size; i++)
Buffer[i] = String[i];
for (size_t i = size, j = 0; i < newsize; i++, j++)
Buffer[i] = StringLiteral[j];
Buffer[newsize] = L'\0';
free();
size = newsize;
String = Buffer;
}
}
}
size_t GetSize() { return size; }
T* GetString() { return String; }
};
_TString<CHAR> TCatA(std::initializer_list<AnyString> list)
{
_TString<CHAR> String;
for (auto iterator = list.begin(), end = list.end(); iterator != end; ++iterator)
String.join(*iterator);
return String;
}
_TString<WCHAR> TCatW(std::initializer_list<AnyString> list)
{
_TString<WCHAR> String;
for (auto iterator = list.begin(), end = list.end(); iterator != end; ++iterator)
String.join(*iterator);
return String;
}
// TString code end
// Main code start
#define EXTENSION_NAME YOUR_EXTENSION_NAME //"my-extension" in ANSI
void WriteToOutputWindow(LPCSTR Text) { OutputDebugStringA(Text); }
void GetProjectDirectory(TString &Path)
{
TCHAR MaxPath[MAX_PATH] = { 0 };
GetModuleFileName(NULL, MaxPath, MAX_PATH);
for (int i = _tcslen(MaxPath), ch = 0; i > 0; i--)
{
if (MaxPath[i] == TEXT('\\') && ++ch == 2)
break;
else
MaxPath[i] = TEXT('\0');
}
Path.join(MaxPath);
}
void GetDataDirectory(TString &Path)
{
GetProjectDirectory(Path);
TCHAR TempBuffer[MAX_PATH] = { 0 }, FinalBuffer[MAX_PATH] = { 0 };
for (size_t i = Path.GetSize() - 1, ch = 0, j = 0; i > 0; i--, j++)
{
if (Path[i] == TEXT('\\') && ++ch == 2)
break;
else
TempBuffer[j] = Path[i];
}
for (size_t i = _tcslen(TempBuffer), j = 0; i > 0; i--, j++)
FinalBuffer[j] = TempBuffer[i - 1];
Path.join(FinalBuffer);
}
bool Restart()
{
int msgboxID = MessageBox(NULL, TEXT("Firefox has been closed. Save changes and press \"Yes\" to run again."), TEXT("Run again?"), MB_YESNO | MB_ICONQUESTION);
switch (msgboxID)
{
case IDYES:
return true;
case IDNO:
return false;
}
}
int WINAPI _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrev, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
{
CMDREDIRECTION Window(WriteToOutputWindow);
TString ExtensionDir;
TString DataDir;
if (Window.Start())
{
GetProjectDirectory(ExtensionDir);
GetDataDirectory(DataDir);
ExtensionDir.join(TEXT("Firefox SDK\\"));
if (!PathIsDirectory(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer(TCatA({ "mkdir \"", ExtensionDir.GetString(), "\"" }), 0, "", true);
if (PathIsDirectoryEmpty(ExtensionDir))
{
MessageBox(NULL, TCat({ TEXT("Firefox SDK directory is empty, please copy SDK files to this directory: "), ExtensionDir.GetString() }), TEXT("Failure!"), MB_ICONINFORMATION);
return EXIT_FAILURE;
}
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", ExtensionDir.GetString() }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer("bin\\activate", 0, "", true);
ExtensionDir.join(TCat({ TEXT(EXTENSION_NAME), TEXT("\\") }));
if (!PathIsDirectory(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer(TCatA({ "mkdir ", EXTENSION_NAME }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", EXTENSION_NAME }), 0, "", true);
if (PathIsDirectoryEmpty(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer("cfx init", 0, "", true);
do
{
/*
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", DataDir.GetString() }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"main.js\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\lib\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.js\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y /EXCLUDE:exclude.txt" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.html\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.png\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.css\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
*/
Window.WriteToCmdAndWaitForAnswer("cfx run --profiledir=\"./dir\"", 0, "Program terminated successfully.", true);
} while (Restart());
}
return EXIT_SUCCESS;
}
// Main code end

Resources