Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

TDL: Protocol for .dan.g.'s ToDoList, Useful for SVN Users

, 25 Apr 2008
Register a fake protocol of TDL: to make tdl:///filename.tdl?tid available
tdl-app_exe.zip
TdlApp.exe
tdl-app_src.zip
MainFormUnit.dfm
res
tdl.ico
TdlApp.bdsproj
TdlApp.res
tdl_scr.zip
ToDoList.wsf
//---------------------------------------------------------------------------

#include <vcl.h>
#include <registry.hpp>
#include <iniFiles.hpp>
#pragma hdrstop

#include "MainFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
    OpenDialog->InitialDir = ExtractFileDir(Application->ExeName);

    wrapper.LinkStyle = HyperlinkWrapper::Style(clBlue, false, false);
    wrapper.HoverStyle = HyperlinkWrapper::Style(clBlue, false, true);

    wrapper.wrap(LabelAbout);

    wrapper.wrap(LabelReg);
    wrapper.wrap(LabelUnreg);

    wrapper.wrap(LabelSaveReg);
    wrapper.wrap(LabelSaveIni);
    wrapper.wrap(LabelSelectExe);
    wrapper.wrap(LabelChangeStorage);

    wrapper.wrap(LabelClose);

    LabelReg->OnClick = onReg;
    LabelUnreg->OnClick = onUnreg;
    LabelAbout->OnClick = onAbout;

    LabelSaveReg->OnClick = onToReg;
    LabelSaveIni->OnClick = onToIni;
    LabelChangeStorage->OnClick = onChangeStorage;
    LabelSelectExe->OnClick = onSelect;

    LabelClose->OnClick = onClose;

    loadProtocol();
    loadConfiguration();
    layoutProtocolComponents();
    layoutConfigurationComponents();
}

bool __fastcall TMainForm::parse() {
    int count = ParamCount();
    if (count < 1 || todolist.IsEmpty()) {
        return false;
    }

    AnsiString url = ParamStr(1);
    AnsiString lcaseUrl = url.LowerCase();

    if (lcaseUrl.SubString(0, 4) != "tdl:") {
        showError(TEXT("URL Error"), WideString(TEXT("It's not a TDL url:\n")) + url);
        return true;
    }

    int i = 5;
    for (; i < 8 && i < url.Length(); i++) {
        if (lcaseUrl[i] != '/') {
            break;
        }
    }

    if (i == url.Length()) {
        return true;
    }

    AnsiString tdl = url.SubString(i, url.Length() - i + 1);
    AnsiString tid;

    i = tdl.Pos("?");
    if (i > 0) {
        tid = tdl.SubString(i + 1, tdl.Length() - i);
        tdl = tdl.SubString(1, i - 1);
    }

    if (!tdl.IsEmpty() && tdl.SubString(tdl.Length(), 1) == "/") {
        tdl = tdl.SubString(1, tdl.Length() - 1);
    }

    if (tdl.IsEmpty()) {
        return true;
    }

    TReplaceFlags flags;
    flags << rfReplaceAll;
    tdl = StringReplace(tdl, "%20", " ", flags);
    tdl = StringReplace(tdl, "/", "\\", flags);

    AnsiString cmd = TEXT("\"");
    cmd += todolist;
    cmd += "\" \"";
    cmd += tdl;
    cmd += "\"";
    if (!tid.IsEmpty()) {
        cmd += " -tid ";
        cmd += tid;
    }

    WinExec(cmd.c_str(), SW_SHOW);

    return true;
}

void __fastcall TMainForm::showError(const TCHAR* caption, const TCHAR* message) {
    MessageBox(NULL, message, caption, MB_OK | MB_ICONEXCLAMATION);
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::loadProtocol() {
    TRegistry* reg = new TRegistry();
    reg->RootKey = HKEY_CLASSES_ROOT;

    isParser = false;
    registered = reg->OpenKey("\\TDL", false);
    if (registered) {
        if (reg->ValueExists("URL Protocol")) {
            if(reg->OpenKey("shell\\open\\command", false)) {
                AnsiString value = reg->ReadString("");
                value = value.LowerCase();
                AnsiString exe = Application->ExeName.LowerCase();
                isParser = value.Pos(exe) > 0;
            }
        }
    }

    delete reg;
}

void __fastcall TMainForm::loadConfiguration() {
    AnsiString dir = ExtractFileDir(Application->ExeName);
    if (dir[dir.Length()] != '\\') {
        dir += "\\";
    }

    AnsiString iniFilename = dir + "tdl.ini";
    if (FileExists(iniFilename)) {
        TIniFile* ini = new TIniFile(iniFilename);
        todolist = ini->ReadString("tdl", "todolist", "");
        useIni = !todolist.IsEmpty();
        delete ini;
    }

    if (!useIni) {
        TRegistry* reg = new TRegistry();
        reg->RootKey = HKEY_CLASSES_ROOT;

        isParser = false;
        bool r = reg->OpenKey("\\TDL", false);
        if (r) {
            if (reg->ValueExists("todolist")) {
                todolist = reg->ReadString("todolist");
            }
        }
        reg->CloseKey();
        delete reg;
    }
}

void __fastcall TMainForm::layoutProtocolComponents() {
    bool reg = false;
    bool unreg = false;

    if (registered) {
        if (isParser) {
            LabelRegMessage->Caption = "The TDL protocol is registered.";
        } else {
            LabelRegMessage->Caption = "The TDL protocol is registered, \
but registered URL parser isn't this executable.";
            reg = true;
        }
        unreg = true;
    } else {
        LabelRegMessage->Caption = "The TDL protocol isn't registered.";
        reg = true;
    }

    LabelReg->Visible = reg;
    LabelUnreg->Visible = unreg;
}

void __fastcall TMainForm::layoutConfigurationComponents() {
    bool select = false;
    bool toReg = false;
    bool toIni = false;
    bool change = false;

    LabelPath->Caption = todolist;
    if (todolist.IsEmpty()) {
        LabelConfigMessage->Caption = "The path of ToDoList executable is not configured.";
        toReg = true;
        toIni = true;        
    } else {
        if (useIni) {
            LabelConfigMessage->Caption = "The path of ToDoList executable is configured \
and stored in tdl.ini. The path is";
            LabelChangeStorage->Caption = "Change the storage to registry";
        } else {
            LabelConfigMessage->Caption = "The path of ToDoList executable is configured \
and stored in registry. The path is";
            LabelChangeStorage->Caption = "Change the storage to tdl.ini";
        }
        select = true;
        change = true;
    }

    LabelSaveReg->Visible = toReg;
    LabelSaveIni->Visible = toIni;
    LabelChangeStorage->Visible = change;
    LabelSelectExe->Visible = select;
}

void __fastcall TMainForm::regProtocol() {
    TRegistry* reg = new TRegistry();
    reg->RootKey = HKEY_CLASSES_ROOT;
    bool r = reg->OpenKey("\\TDL", true);
    if (!r) throw WideString(TEXT("error"));

    reg->WriteString("", "URL: ToDoList Protocol (TDL)");
    reg->WriteString("URL Protocol", "");

    r = reg->OpenKey("shell\\open\\command", true);
    if (!r) throw WideString(TEXT("error"));
    AnsiString exePath = AnsiString("\"");
    exePath += Application->ExeName;
    exePath += "\" \"%1\"";
    reg->WriteString("", exePath);

    reg->CloseKey();
    delete reg;

    registered = true;
    isParser = true;
    layoutProtocolComponents();

}

void __fastcall TMainForm::unregProtocol() {
    TRegistry* reg = new TRegistry();
    reg->RootKey = HKEY_CLASSES_ROOT;
    reg->DeleteKey("\\TDL");
    delete reg;

    registered = false;
    isParser = false;
    layoutProtocolComponents();
}

bool __fastcall TMainForm::selectTodolist() {
    if (!todolist.IsEmpty()) {
        OpenDialog->FileName = todolist;
    }
    bool r = OpenDialog->Execute();
    if (!r) {
        return false;
    }

    todolist = OpenDialog->FileName;
    return true;
}

void __fastcall TMainForm::configToReg() {
    AnsiString dir = ExtractFileDir(Application->ExeName);
    if (dir[dir.Length()] != '\\') {
        dir += "\\";
    }

    AnsiString iniFilename = dir + "tdl.ini";
    if (FileExists(iniFilename)) {
        DeleteFile(iniFilename);
    }

    TRegistry* reg = new TRegistry();
    reg->RootKey = HKEY_CLASSES_ROOT;

    isParser = false;
    bool r = reg->OpenKey("\\TDL", false);
    if (r) {
        reg->WriteString("todolist", todolist);
    }
    reg->CloseKey();
    delete reg;

    useIni = false;
}

void __fastcall TMainForm::configToIni() {
    TRegistry* reg = new TRegistry();
    reg->RootKey = HKEY_CLASSES_ROOT;

    isParser = false;
    bool r = reg->OpenKey("\\TDL", false);
    if (r) {
        if (reg->ValueExists("todolist")) {
            reg->DeleteValue("todolist");
        }
    }
    reg->CloseKey();
    delete reg;

    AnsiString dir = ExtractFileDir(Application->ExeName);
    if (dir[dir.Length()] != '\\') {
        dir += "\\";
    }

    AnsiString iniFilename = dir + "tdl.ini";
    TIniFile* ini = new TIniFile(iniFilename);
    ini->WriteString("tdl", "todolist", todolist);
    delete ini;

    useIni = true;
}

void __fastcall TMainForm::onReg(TObject* sender) {
    try {
        regProtocol();
    } catch (WideString& err) {
        ShowMessage("Error Occur!");
    }
}

void __fastcall TMainForm::onUnreg(TObject* sender) {
    unregProtocol();
}

void __fastcall TMainForm::onSelect(TObject* sender) {
    if (selectTodolist()) {
        if (useIni) {
            configToIni();
        } else {
            configToReg();
        }
        layoutConfigurationComponents();
    }
}

void __fastcall TMainForm::onToReg(TObject* sender) {
    if (selectTodolist()) {
        configToReg();
        layoutConfigurationComponents();
    }
}

void __fastcall TMainForm::onToIni(TObject* sender) {
    if (selectTodolist()) {
        configToIni();
        layoutConfigurationComponents();
    }
}

void __fastcall TMainForm::onChangeStorage(TObject* sender) {
    if (useIni) {
        configToReg();
    } else {
        configToIni();
    }
    layoutConfigurationComponents();
}

void __fastcall TMainForm::onClose(TObject* sender) {
    Close();
}

void __fastcall TMainForm::onAbout(TObject* sender) {
    ShellExecute(Application->Handle, TEXT("open"),
        TEXT("http://www.codeproject.com/useritems/TDL_protocol_for_ToDoList.asp"),
        NULL, NULL, SW_SHOW);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

jamesfancy

China China
James Fancy, is a software engineer from China. He enjoys and familiar with Java, C++ and some script languages.
 
If you can read Chinese word, here is one of James Fancy's BLOG:
http://hi.baidu.com/jamesfancy

| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 25 Apr 2008
Article Copyright 2007 by jamesfancy
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid