Archive for the 'Source code' Category

SETTING the settings

Saturday, June 24th, 2006

So you’ve gotten bored and you started looking in StringDefs.h. You notice that there’s a bunch of SETTING_SOME_OBSCURE_OPTION. When you search for it in other places in the source, you end up in resource.h and SomePage.cpp (and of course StringDefs.h) (where ‘SomePage’ is the name of one of the settings pages).

“How can these options then be used elsewhere if there’s no code to back it up? So DC++ completely ignores every single option there is?”
No, DC++ doesn’t. You see, all of the things in StringDefs.h that have SETTINGS_ before it are captions (text) in the settings pages. Meaning, they aren’t used as options. The names of the settings are instead SOME_OBSCURE_OPTION, and if you search for that, I assure you that you will see more places than above files. (And you can call the option with SETTING(SOME_OBSCURE_OPTION) or BOOLSETTING(SOME_OBSCURE_OPTION).)

SCH proudly presents $Search

Monday, June 19th, 2006

Ah, yes, today is a “why the NMDC protocol suck and ADC is so great”-post. And today’s protocol bit is brought to you by $Search (paid and sponsored by SCH in ADC) and the file types used. (You should have a look at the Search types post I made a while ago.)

Now, on to the (NMDC) protocol bit. All of the search types are “hard coded” into the protocol, meaning you will need to upgrade other clients to respond to your file type searches. This is unfortunately not enough of the NMDC sillyness. When you pick a certain file type in DC++, DC++ will change the caption of your choice (”Audio” eg) and to a number. This number is predefined (as the wiki post says) and cannot be changed (because otherwise, you’d recieve wrong search results or not get any - depending on what you change the number to). This basically means that you cannot tell DC++ (code wise, considering there is no way to do it in the GUI) to “search for _filename_ but only include audio extension AND video extension”. This is because there is no way to combine the different numbers. Now you’re thinking “but can’t you add them and the send that number out?”, and sure, you can do that. But you won’t get the result your after. Eg, “Audio” is 2 and “Compressed files” is 3. Now, if you add these, they (of course) become 5. Now, the problem is that 5 is “Executables”, making all of the other clients think you’re after “executables” and not “audio” and “compressed files”.

“Sigh… Every time you talk about NMDC, I hear something bad… Fine. So, what’s so good with ADC then?”

Ah, my dearest Watson, it is very simple. In ADC’s SCH, one can specify a “EX” (”extension”) when searching, and the responding client have to match files with atleast one of those EXs. This means that we can specify completely what kind of file types we want - even if the other client hasn’t hard coded any file extensions in its client).

Me, myself and Unsigned

Monday, June 12th, 2006

One of the problems when creating software is to predict and know what kind of input people will give when they fiddle around in the settings of the program. DC++ no less also has this issue. Though, while it’s easy to picture (as a programmer) what the user input will be, the code outcome might not always be what the programmer originally intended.

The issue I’m going to talk about today is an issue that arose with people upgrading from DC++ 0.674 to 0.691. (I don’t know if the problem was or not possible with 0.674.)

A bug report and patch was swiftly created and will most likely be introduced in “0.692″ (upcoming version).

If you look at the patch, you will see that lines starting with ‘-’ is removed and ‘+’ is added. With this knowledge, the only “real” change you will see in the patch is that instead of “short” it says “unsigned short”. What this change really does lies in the way C++ (DC++ is written in C++) is designed.
(If you have programming knowledge, you know a short is a type for variables/functions etc. For the no-programming-knowledge-people; Consider that you have a box. This box can store a value, but only one, at any given time. Now, this box have to have a ‘type’, meaning it can only contain values of that certain type. short is one of those types.)

In C++, if a type has nothing before it, it is ’signed’; This means that it can contain values up to 2^15. The problem is that socket ports can reach 2^16. And this is where the ‘unsigned’ comes in the picture. If a type has ‘unsigned’ before, it not only support 2^15, but also 2^16. We come to the conclusion that using ‘unsigned’ before removes our issue.

Another thing you might notice with the current behaviour, it is that if you input a value above 2^15 (but below 2^16), you will then use - 2^16, this of course leading to a negative value. An interesting thing is that if you input something above 2^16, the value used will then also be - 2^16.

Creating a new Settings page

Thursday, March 9th, 2006

Creating a new Settings page

Here you go. A nice ‘tutorial’ on creating new Settings pages. I know I’ve removed the help file bit, but it isn’t neccesary. (I know, the formatting is terrible, but I don’t feel like fixing it.)

 

1) Include the header file to PropertiesDlg.cpp

#include “NewPage.h”

 

2) In the same file, in PropertiesDlg::PropertiesDlg(HWND parent, …) { }, add:

pages[n++] = new NewPage(s);

 

3) In PropertiesDlg.h, change the number on this line:

enum { numPages = 14 };

Just change the number to how many Settings-pages you have.

4) In DCPlusPlus.vcproj, add these lines:

<File
RelativePath=”.\windows\NewPage.cpp”>
</File>
<File
RelativePath=”.\windows\NewPage.h”>
</File>

 

5) In the NewPage.cpp, add at the top:
#include “stdafx.h”
#include “../client/DCPlusPlus.h”
#include “Resource.h”

#include “NewPage.h”
#include “CommandDlg.h”

#include “../client/SettingsManager.h”

6) Add:
LRESULT NewPage::onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
PropPage::translate((HWND)(*this), texts); // ‘texts’ here is a static TextItem array. Omit if desired.
PropPage::read((HWND)*this, items, 0, 0); // ‘items’ here is a static Item array. Omit if desired.

// Do specialized reading here
return TRUE;
}

7) Add:
void NewPage::write() {
PropPage::write((HWND)*this, items, 0, 0); // ‘items’ here is a static Item array, the very same variable as on 6). Omit if desired.
}

8.1) If you want to have text in your page, add:
PropPage::TextItem NewPage::texts[] = {
{ IDC_SETTINGS_SOME_SETTING, ResourceManager::SOME_TEXT },
{ IDC_SETTINGS_ANOTHER_SETTING, ResourceManager::ANOTHER_TEXT },
{ 0, ResourceManager::SETTINGS_AUTO_AWAY } // Pretty much used everywhere else… You can might aswell include it.
};
Remember that you have to have the ‘texts’ array included.

8.2) If you want to have items in your page, add:
PropPage::Item NewPage::items[] = {
{ IDC_SOME_ITEM, SettingsManager::SOME_TEXT_BLAH, PropPage::T_INT },
{ IDC_ANOTHERITEM, SettingsManager::ANOTHER_TEXT_BLAH, PropPage::T_STRING },
{ 0, 0, PropPage::T_END }
};
Depending on the item, use T_INT or T_STRING.

Well, you get the hang of it there.

9) In NewPage.h, add:
#ifndef NEWPAGE_H
#define NEWPAGE_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <atlcrack.h>
#include “PropPage.h”
#include “ExListViewCtrl.h”

class NewPage : public CPropertyPage<IDD_NEWPAGE>, public PropPage
{
public:
NewPage(SettingsManager *s) : PropPage(s) {
SetTitle(CTSTRING(SETTINGS_NEWPAGE));
m_psp.dwFlags |= PSP_HASHELP;
};

virtual ~NewPage() {
};

BEGIN_MSG_MAP(NewPage)
MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog)
END_MSG_MAP()

LRESULT onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);

// Common PropPage interface
PROPSHEETPAGE *getPSP() { return (PROPSHEETPAGE *)*this; }
virtual void write();

protected:

static Item items[]; // If you want it that is…
static TextItem texts[]; // If you want it that is…
};

#endif //NEWPAGE_H

10) Last, you need to add it to resource.h:

#define IDD_NEWPAGE 123
11) Add SETTING_NEWPAGE to StringDefs.h.