- Description field is not done yet.
- Download.c is taken from getfirefox.
svn path=/trunk/; revision=25168
<directory name="devmgr">
<xi:include href="devmgr/devmgr.rbuild" />
</directory>
+<directory name="downloader">
+ <xi:include href="downloader/downloader.rbuild" />
+</directory>
<directory name="games">
<xi:include href="games/games.rbuild" />
</directory>
--- /dev/null
+<tree Version="1"> <!-- Application version this tree is made for -->\r
+ <category name="Internet & Network" icon="1">\r
+ <category name="Browsers">\r
+ <application name="Firefox">\r
+ <description>The most popular free webbrowser out there.</description>\r
+ <location>http://links.reactos.org/getfirefox</location>\r
+ </application>\r
+ </category>\r
+ </category>\r
+ <category name="Office" icon="2">\r
+ </category>\r
+ <category name="Graphics" icon="3">\r
+ </category>\r
+ <category name="Multimedia" icon="4">\r
+ </category>\r
+ <category name="Development" icon="5">\r
+ </category>\r
+ <category name="Games & Fun" icon="6">\r
+ </category>\r
+ <category name="Tools" icon="7">\r
+ </category>\r
+ <category name="Others" icon="8">\r
+ </category>\r
+</tree>
\ No newline at end of file
--- /dev/null
+/*
+ * PROJECT: ReactOS Downloader (was GetFirefox)
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/applications/downloader/download.c
+ * PURPOSE: Displaying a download dialog
+ * COPYRIGHT: Copyright 2001 John R. Sheets (for CodeWeavers)
+ * Copyright 2004 Mike McCormack (for CodeWeavers)
+ * Copyright 2005 Ge van Geldorp (gvg@reactos.org)
+ */
+/*
+ * Based on Wine dlls/shdocvw/shdocvw_main.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define COBJMACROS
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <commctrl.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <urlmon.h>
+
+#include "resources.h"
+#include "structures.h"
+
+#define NDEBUG
+#include <debug.h>
+
+extern struct Application* SelectedApplication;
+
+typedef struct _IBindStatusCallbackImpl
+ {
+ const IBindStatusCallbackVtbl *vtbl;
+ LONG ref;
+ HWND hDialog;
+ BOOL *pbCancelled;
+ } IBindStatusCallbackImpl;
+
+static HRESULT WINAPI
+dlQueryInterface(IBindStatusCallback* This, REFIID riid, void** ppvObject)
+{
+ if (NULL == ppvObject)
+ {
+ return E_POINTER;
+ }
+
+ if (IsEqualIID(riid, &IID_IUnknown) ||
+ IsEqualIID(riid, &IID_IBindStatusCallback))
+ {
+ IBindStatusCallback_AddRef( This );
+ *ppvObject = This;
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+dlAddRef(IBindStatusCallback* iface)
+{
+ IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI
+dlRelease(IBindStatusCallback* iface)
+{
+ IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+ DWORD ref = InterlockedDecrement(&This->ref);
+
+ if( !ref )
+ {
+ DestroyWindow( This->hDialog );
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI
+dlOnStartBinding(IBindStatusCallback* iface, DWORD dwReserved, IBinding* pib)
+{
+ DPRINT1("OnStartBinding not implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlGetPriority(IBindStatusCallback* iface, LONG* pnPriority)
+{
+ DPRINT1("GetPriority not implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnLowResource( IBindStatusCallback* iface, DWORD reserved)
+{
+ DPRINT1("OnLowResource not implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnProgress(IBindStatusCallback* iface, ULONG ulProgress,
+ ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
+{
+ IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+ HWND Item;
+ LONG r;
+ WCHAR OldText[100];
+
+ Item = GetDlgItem(This->hDialog, IDC_PROGRESS);
+ if (NULL != Item && 0 != ulProgressMax)
+ {
+ SendMessageW(Item, PBM_SETPOS, (ulProgress * 100) / ulProgressMax, 0);
+ }
+
+ Item = GetDlgItem(This->hDialog, IDC_STATUS);
+ if (NULL != Item && NULL != szStatusText)
+ {
+ SendMessageW(Item, WM_GETTEXT, sizeof(OldText) / sizeof(OldText[0]),
+ (LPARAM) OldText);
+ if (sizeof(OldText) / sizeof(OldText[0]) - 1 <= wcslen(OldText) ||
+ 0 != wcscmp(OldText, szStatusText))
+ {
+ SendMessageW(Item, WM_SETTEXT, 0, (LPARAM) szStatusText);
+ }
+ }
+
+ SetLastError(0);
+ r = GetWindowLongPtrW(This->hDialog, GWLP_USERDATA);
+ if (0 != r || 0 != GetLastError())
+ {
+ *This->pbCancelled = TRUE;
+ DPRINT("Cancelled\n");
+ return E_ABORT;
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnStopBinding(IBindStatusCallback* iface, HRESULT hresult, LPCWSTR szError)
+{
+ DPRINT1("OnStopBinding not implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlGetBindInfo(IBindStatusCallback* iface, DWORD* grfBINDF, BINDINFO* pbindinfo)
+{
+ DPRINT1("GetBindInfo not implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnDataAvailable(IBindStatusCallback* iface, DWORD grfBSCF,
+ DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
+{
+ DPRINT1("OnDataAvailable implemented\n");
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnObjectAvailable(IBindStatusCallback* iface, REFIID riid, IUnknown* punk)
+{
+ DPRINT1("OnObjectAvailable implemented\n");
+
+ return S_OK;
+}
+
+static const IBindStatusCallbackVtbl dlVtbl =
+{
+ dlQueryInterface,
+ dlAddRef,
+ dlRelease,
+ dlOnStartBinding,
+ dlGetPriority,
+ dlOnLowResource,
+ dlOnProgress,
+ dlOnStopBinding,
+ dlGetBindInfo,
+ dlOnDataAvailable,
+ dlOnObjectAvailable
+};
+
+static IBindStatusCallback*
+CreateDl(HWND Dlg, BOOL *pbCancelled)
+{
+ IBindStatusCallbackImpl *This;
+
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(IBindStatusCallbackImpl));
+ This->vtbl = &dlVtbl;
+ This->ref = 1;
+ This->hDialog = Dlg;
+ This->pbCancelled = pbCancelled;
+
+ return (IBindStatusCallback*) This;
+}
+
+static DWORD WINAPI
+ThreadFunc(LPVOID Context)
+{
+ //static const WCHAR szUrl[] = DownloadUrl;
+ IBindStatusCallback *dl;
+ WCHAR path[MAX_PATH];
+ LPWSTR p;
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ HWND Dlg = (HWND) Context;
+ DWORD r;
+ BOOL bCancelled = FALSE;
+ BOOL bTempfile = FALSE;
+
+ /* built the path for the download */
+ p = wcsrchr(SelectedApplication->Location, L'/');
+ if (NULL == p)
+ {
+ goto end;
+ }
+ if (! GetTempPathW(MAX_PATH, path))
+ {
+ goto end;
+ }
+ wcscat(path, p + 1);
+
+ /* download it */
+ bTempfile = TRUE;
+ dl = CreateDl(Context, &bCancelled);
+ r = URLDownloadToFileW(NULL, SelectedApplication->Location, path, 0, dl);
+ if (NULL != dl)
+ {
+ IBindStatusCallback_Release(dl);
+ }
+ if (S_OK != r || bCancelled )
+ {
+ goto end;
+ }
+ ShowWindow(Dlg, SW_HIDE);
+
+ /* run it */
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ r = CreateProcessW(path, NULL, NULL, NULL, 0, 0, NULL, NULL, &si, &pi);
+ if (0 == r)
+ {
+ goto end;
+ }
+ CloseHandle(pi.hThread);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+
+end:
+ if (bTempfile)
+ {
+ DeleteFileW(path);
+ }
+ EndDialog(Dlg, 0);
+ return 0;
+}
+
+INT_PTR CALLBACK
+DownloadProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ HANDLE Thread;
+ DWORD ThreadId;
+ HWND Item;
+
+ switch (Msg)
+ {
+ case WM_INITDIALOG:/*
+ Icon = LoadIconW((HINSTANCE) GetWindowLongPtr(Dlg, GWLP_HINSTANCE),
+ MAKEINTRESOURCEW(IDI_ICON_MAIN));
+ if (NULL != Icon)
+ {
+ SendMessageW(Dlg, WM_SETICON, ICON_BIG, (LPARAM) Icon);
+ SendMessageW(Dlg, WM_SETICON, ICON_SMALL, (LPARAM) Icon);
+ }*/
+ SetWindowLongPtrW(Dlg, GWLP_USERDATA, 0);
+ Item = GetDlgItem(Dlg, IDC_PROGRESS);
+ if (NULL != Item)
+ {
+ SendMessageW(Item, PBM_SETRANGE, 0, MAKELPARAM(0,100));
+ SendMessageW(Item, PBM_SETPOS, 0, 0);
+ }/*
+ Item = GetDlgItem(Dlg, IDC_REMOVE);
+ if (NULL != Item)
+ {
+ if (GetShortcutName(ShortcutName) &&
+ INVALID_FILE_ATTRIBUTES != GetFileAttributesW(ShortcutName))
+ {
+ SendMessageW(Item, BM_SETCHECK, BST_CHECKED, 0);
+ }
+ else
+ {
+ SendMessageW(Item, BM_SETCHECK, BST_UNCHECKED, 0);
+ ShowWindow(Item, SW_HIDE);
+ }
+ }*/
+ Thread = CreateThread(NULL, 0, ThreadFunc, Dlg, 0, &ThreadId);
+ if (NULL == Thread)
+ {
+ return FALSE;
+ }
+ CloseHandle(Thread);
+ return TRUE;
+
+ case WM_COMMAND:
+ if (wParam == IDCANCEL)
+ {
+ SetWindowLongPtrW(Dlg, GWLP_USERDATA, 1);
+ PostMessage(Dlg, WM_CLOSE, 0, 0);
+ }
+ return FALSE;
+
+ case WM_CLOSE:
+ EndDialog(Dlg, 0);
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
--- /dev/null
+<?xml version="1.0"?>\r
+<!DOCTYPE project SYSTEM "tools/rbuild/project.dtd">\r
+<module name="downloader" type="win32gui" installbase="system32" installname="downloader.exe" allowwarnings="true" stdlib="host">\r
+ <include base="downloader">.</include>\r
+ <include base="expat">.</include>\r
+\r
+ <define name="UNICODE" />\r
+ <define name="_UNICODE" />\r
+ <define name="__USE_W32API" />\r
+ <define name="WINVER">0x0501</define>\r
+ <define name="_WIN32_IE>0x0600</define>\r
+\r
+ <library>kernel32</library>\r
+ <library>ntdll</library>\r
+ <library>user32</library>\r
+ <library>gdi32</library>\r
+ <library>shell32</library>\r
+ <library>comctl32</library>\r
+ <library>msimg32</library>\r
+ <library>shlwapi</library>\r
+ <library>urlmon</library>\r
+ <library>uuid</library>\r
+ <library>expat</library>\r
+\r
+ <file>main.c</file>\r
+ <file>xml.c</file>\r
+ <file>download.c</file>\r
+ <file>downloader.rc</file>\r
+</module>\r
--- /dev/null
+#include <windows.h>\r
+#include "resources.h"\r
+\r
+#define REACTOS_STR_FILE_DESCRIPTION "Download !\0"\r
+#define REACTOS_STR_INTERNAL_NAME "downloader\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME "downloader.exe\0"\r
+\r
+#include <reactos/version.rc>\r
+\r
+#include "resources/generic.rc"\r
+#include "resources/en.rc"\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*
+ * PROJECT: ReactOS Downloader
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/applications/downloader/xml.c
+ * PURPOSE: Main program
+ * PROGRAMMERS: Maarten Bosma
+ */
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+#include <stdio.h>
+#include "resources.h"
+#include "structures.h"
+
+HWND hCategories, hApps, hDescription, hBtnDownload, hBtnUpdate, hBtnHelp;
+HBITMAP hLogo;
+
+struct Category Root;
+struct Application* SelectedApplication;
+
+INT_PTR CALLBACK DownloadProc (HWND, UINT, WPARAM, LPARAM);
+BOOL ProcessXML (const char* filename, struct Category* Root);
+void FreeTree (struct Category* Node);
+
+
+void ShowMessage (WCHAR* title, WCHAR* message)
+{
+ SETTEXTEX Text = {ST_SELECTION, 1200};
+
+ SendMessage(hDescription, WM_SETTEXT, 0, 0);
+ SendMessage(hDescription, EM_SETTEXTEX, (WPARAM)&Text, (LPARAM)title);
+ SendMessage(hDescription, EM_SETTEXTEX, (WPARAM)&Text, (LPARAM)L"\n----------------------------------------\n");
+ SendMessage(hDescription, EM_SETTEXTEX, (WPARAM)&Text, (LPARAM)message);
+}
+
+void AddItems (HWND hwnd, struct Category* Category, struct Category* Parent)
+{
+ TV_INSERTSTRUCT Insert;
+
+ Insert.item.lParam = (UINT)Category;
+ Insert.item.mask = TVIF_TEXT|TVIF_PARAM;
+ Insert.item.pszText = Category->Name; //that is okay
+ Insert.item.cchTextMax = lstrlen(Category->Name);
+ Insert.hInsertAfter = TVI_LAST;
+ Insert.hParent = Category->Parent ? Category->Parent->TreeviewItem : TVI_ROOT;
+
+ if(Category->Icon)
+ {
+ Insert.item.iImage = Category->Icon;
+ Insert.item.iSelectedImage = Category->Icon;
+ Insert.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ }
+
+ Category->TreeviewItem = (HTREEITEM)SendMessage(hwnd, TVM_INSERTITEM, 0, (LPARAM)&Insert);
+
+ if(Category->Next)
+ AddItems (hwnd,Category->Next,Parent);
+
+ if(Category->Children)
+ AddItems (hwnd,Category->Children,Category);
+}
+
+void DisplayApps (HWND hwnd, struct Category* Category)
+{
+ struct Application* CurrentApplication = Category->Apps;
+
+ TreeView_DeleteItem(hwnd, TVI_ROOT);
+
+ TV_INSERTSTRUCT Insert;
+ Insert.item.mask = TVIF_TEXT|TVIF_PARAM;
+ Insert.hInsertAfter = TVI_LAST;
+ Insert.hParent = TVI_ROOT;
+
+ while(CurrentApplication)
+ {
+ Insert.item.lParam = (UINT)CurrentApplication;
+ Insert.item.pszText = CurrentApplication->Name;
+ Insert.item.cchTextMax = lstrlen(CurrentApplication->Name);
+ SendMessage(hwnd, TVM_INSERTITEM, 0, (LPARAM)&Insert);
+ CurrentApplication = CurrentApplication->Next;
+ }
+}
+
+void SetupControls (HWND hwnd)
+{
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+
+ // Set up the controls
+ hCategories = CreateWindowEx(0, WC_TREEVIEW, L"Categories", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,
+ 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
+
+ hApps = CreateWindowEx(0, WC_TREEVIEW, L"Applications", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,
+ 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
+
+ hDescription = CreateWindowEx(WS_EX_WINDOWEDGE, RICHEDIT_CLASS, L"", WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY, //|ES_AUTOHSCROLL
+ 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
+
+ hLogo = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_LOGO));
+
+ hBtnHelp = CreateWindow (L"Button", L"", WS_CHILD|WS_VISIBLE|BS_BITMAP, 550, 10, 40, 40, hwnd, 0, hInstance, NULL);
+ hBtnUpdate = CreateWindow (L"Button", L"", WS_CHILD|WS_VISIBLE|BS_BITMAP, 500, 10, 40, 40, hwnd, 0, hInstance, NULL);
+ hBtnDownload = CreateWindow (L"Button", L"", WS_CHILD|WS_VISIBLE|BS_BITMAP, 330, 505, 140, 33, hwnd, 0, hInstance, NULL);
+
+ SendMessage (hBtnHelp, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_HELP)));
+ SendMessage (hBtnUpdate, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,(LPARAM)(HANDLE)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_UPDATE)));
+ SendMessage (hBtnDownload, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,(LPARAM)(HANDLE)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DOWNLOAD)));
+
+ // Create Tree Icons
+ HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLORDDB, 1, 1);
+ SendMessage(hCategories, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hImageList);
+ SendMessage(hApps, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hImageList);
+
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_0)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_1)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_2)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_3)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_4)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_5)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_6)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_7)), NULL);
+ ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_8)), NULL);
+
+ // Fill the TreeViews
+ ProcessXML ("C:\\reactos\\base\\applications\\downloader\\apps.xml", &Root);
+ AddItems (hCategories, Root.Children, NULL);
+}
+
+static void ResizeControl (HWND hwnd, int x1, int y1, int x2, int y2)
+{
+ // Make resizing a little easier
+ MoveWindow(hwnd, x1, y1, x2-x1, y2-y1, TRUE);
+}
+
+static void DrawBitmap (HWND hwnd, int x, int y, HBITMAP hBmp)
+{
+ BITMAP bm;
+ PAINTSTRUCT ps;
+
+ HDC hdc = BeginPaint(hwnd, &ps);
+ HDC hdcMem = CreateCompatibleDC(hdc);
+
+ SelectObject(hdcMem, hBmp);
+ GetObject(hBmp, sizeof(bm), &bm);
+
+ //BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
+ TransparentBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, 0xFFFFFF);
+
+ DeleteDC(hdcMem);
+ EndPaint(hwnd, &ps);
+}
+
+LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+ switch (Message)
+ {
+ case WM_CREATE:
+ {
+ SetupControls(hwnd);
+ ShowMessage(L"ReactOS Downloader", L"Welcome to ReactOS's Downloader\nPlease choose a category on the right. This is version 0.5.");
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ DrawBitmap(hwnd, 10, 12, hLogo);
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ if(HIWORD(wParam) == BN_CLICKED)
+ {
+ if (lParam == (LPARAM)hBtnDownload)
+ {
+ DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_DOWNLOAD), 0, DownloadProc);
+ }
+ else if (lParam == (LPARAM)hBtnUpdate)
+ {
+ ShowMessage (L"Update", L"Feature not implemented yet.");
+ }
+ else if (lParam == (LPARAM)hBtnHelp)
+ {
+ ShowMessage (L"Help", L"Choose a category on the right, then choose a application and click the download button.To update the application information click the button next to the help button.");
+ }
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR data = (LPNMHDR)lParam;
+ if(data->code == TVN_SELCHANGED)
+ {
+ if(data->hwndFrom == hCategories)
+ {
+ DisplayApps (hApps, (struct Category*) ((LPNMTREEVIEW)lParam)->itemNew.lParam);
+ }
+ else if(data->hwndFrom == hApps)
+ {
+ SelectedApplication = (struct Application*) ((LPNMTREEVIEW)lParam)->itemNew.lParam;
+ ShowMessage(SelectedApplication->Name, SelectedApplication->Description);
+ }
+ }
+ }
+ break;
+
+ case WM_SIZE:
+ {
+ int Split_Hozizontal = (HIWORD(lParam)-(45+60))/2 + 60;
+ int Split_Vertical = 200;
+
+ ResizeControl(hCategories, 10, 60, Split_Vertical, HIWORD(lParam)-10);
+ ResizeControl(hApps, Split_Vertical+5, 60, LOWORD(lParam)-10, Split_Hozizontal);
+ ResizeControl(hDescription, Split_Vertical+5, Split_Hozizontal+5, LOWORD(lParam)-10, HIWORD(lParam)-50);
+
+ MoveWindow(hBtnHelp, LOWORD(lParam)-50, 10, 40, 40, 0);
+ MoveWindow(hBtnUpdate, LOWORD(lParam)-100, 10, 40, 40, 0);
+ MoveWindow(hBtnDownload, (Split_Vertical+LOWORD(lParam))/2-70, HIWORD(lParam)-45, 140, 35, 0);
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ DeleteObject(hLogo);
+ FreeTree(Root.Children);
+ PostQuitMessage(0);
+ return 0;
+ }
+ break;
+ }
+
+ return DefWindowProc (hwnd, Message, wParam, lParam);
+}
+
+INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst,
+ LPSTR lpCmdLine, INT nCmdShow)
+{
+ HWND hwnd;
+
+ LoadLibrary(L"riched20.dll");
+ InitCommonControls();
+
+ // Create the window
+ WNDCLASSEX WndClass = {0};
+ WndClass.cbSize = sizeof(WNDCLASSEX);
+ WndClass.lpszClassName = L"Downloader";
+ WndClass.style = CS_HREDRAW | CS_VREDRAW;
+ WndClass.lpfnWndProc = WndProc;
+ WndClass.hInstance = hInstance;
+ WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
+ WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ WndClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(235,233,237));
+
+ RegisterClassEx(&WndClass);
+
+ hwnd = CreateWindow(L"Downloader",
+ L"Download ! - ReactOS Downloader",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 600, 550,
+ NULL, NULL,
+ hInstance,
+ NULL);
+
+ // Show it
+ ShowWindow(hwnd, SW_SHOW);
+ UpdateWindow(hwnd);
+
+ // Message Loop
+ MSG msg;
+ while(GetMessage(&msg,NULL,0,0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
--- /dev/null
+
+#define IDI_MAIN 0x0
+#define IDB_UNDERLINE 0x100
+#define IDB_LOGO 0x101
+#define IDB_HELP 0x102
+#define IDB_UPDATE 0x103
+#define IDB_DOWNLOAD 0x104
+#define IDB_TREEVIEW_ICON_0 0x900
+#define IDB_TREEVIEW_ICON_1 0x901
+#define IDB_TREEVIEW_ICON_2 0x902
+#define IDB_TREEVIEW_ICON_3 0x903
+#define IDB_TREEVIEW_ICON_4 0x904
+#define IDB_TREEVIEW_ICON_5 0x905
+#define IDB_TREEVIEW_ICON_6 0x906
+#define IDB_TREEVIEW_ICON_7 0x907
+#define IDB_TREEVIEW_ICON_8 0x908
+#define IDD_DOWNLOAD 0x100
+#define IDC_PROGRESS 0x1000
+#define IDC_STATUS 0x1001
+#define IDC_REMOVE 0x1002
+
+
--- /dev/null
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
+\r
+IDD_DOWNLOAD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 76\r
+STYLE DS_MODALFRAME | DS_CENTER | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Downloading Firefox"\r
+FONT 8, "MS Shell Dlg"\r
+{\r
+ CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12\r
+ LTEXT "", IDC_STATUS, 10, 30, 200, 10, SS_CENTER\r
+ PUSHBUTTON "Cancel", IDCANCEL, 85, 58, 50, 15, WS_GROUP | WS_TABSTOP\r
+}\r
--- /dev/null
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL\r
+\r
+IDI_MAIN ICON DISCARDABLE "main.ico"\r
+IDB_UNDERLINE BITMAP DISCARDABLE "underline.bmp"\r
+IDB_LOGO BITMAP DISCARDABLE "logo.bmp"\r
+IDB_HELP BITMAP DISCARDABLE "help.bmp"\r
+IDB_UPDATE BITMAP DISCARDABLE "update.bmp"\r
+IDB_DOWNLOAD BITMAP DISCARDABLE "download.bmp"\r
+IDB_TREEVIEW_ICON_0 BITMAP DISCARDABLE "0.bmp"\r
+IDB_TREEVIEW_ICON_1 BITMAP DISCARDABLE "1.bmp"\r
+IDB_TREEVIEW_ICON_2 BITMAP DISCARDABLE "2.bmp"\r
+IDB_TREEVIEW_ICON_3 BITMAP DISCARDABLE "3.bmp"\r
+IDB_TREEVIEW_ICON_4 BITMAP DISCARDABLE "4.bmp"\r
+IDB_TREEVIEW_ICON_5 BITMAP DISCARDABLE "5.bmp"\r
+IDB_TREEVIEW_ICON_6 BITMAP DISCARDABLE "6.bmp"\r
+IDB_TREEVIEW_ICON_7 BITMAP DISCARDABLE "7.bmp"\r
+IDB_TREEVIEW_ICON_8 BITMAP DISCARDABLE "8.bmp"\r
--- /dev/null
+
+struct Application
+{
+ WCHAR Name[0x100];
+ WCHAR Version[0x100];
+ WCHAR Maintainer[0x100];
+ WCHAR Licence[0x100];
+ WCHAR Description[0x400];
+ WCHAR Location[0x100];
+ struct Application* Next;
+};
+
+struct Category
+{
+ WCHAR Name[0x100];
+ //WCHAR Description[0x100];
+ int Icon;
+ HANDLE TreeviewItem;
+ struct Application* Apps;
+ struct Category* Next;
+ struct Category* Children;
+ struct Category* Parent;
+};
--- /dev/null
+/*
+ * PROJECT: ReactOS Downloader
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base\applications\downloader\xml.c
+ * PURPOSE: Parsing of application information xml files
+ * PROGRAMMERS: Maarten Bosma
+ */
+
+#include <libs/expat/expat.h>
+#include <string.h>
+#include <stdio.h>
+#include <windows.h>
+#include "structures.h"
+
+BOOL TagOpen;
+struct Category* Current;
+struct Application* CurrentApplication;
+char CurrentTag [0x100];
+
+void tag_opened (void* usrdata, const char* tag, const char** arg)
+{
+ if(!strcmp(tag, "tree") && !CurrentApplication)
+ {
+ // check version
+ }
+
+ else if(!strcmp(tag, "category") && !CurrentApplication)
+ {
+ if (!Current)
+ {
+ Current = malloc(sizeof(struct Category));
+ memset(Current, 0, sizeof(struct Category));
+ }
+ else if (TagOpen)
+ {
+ Current->Children = malloc(sizeof(struct Category));
+ memset(Current->Children, 0, sizeof(struct Category));
+ Current->Children->Parent = Current;
+ Current = Current->Children;
+ }
+ else
+ {
+ Current->Next = malloc(sizeof(struct Category));
+ memset(Current->Next, 0, sizeof(struct Category));
+ Current->Next->Parent = Current->Parent;
+ Current = Current->Next;
+ }
+ TagOpen = TRUE;
+
+ int i;
+ for (i=0; arg[i]; i+=2)
+ {
+ if(!strcmp(arg[i], "name"))
+ {
+ MultiByteToWideChar(CP_ACP, 0, arg[i+1], -1, Current->Name, 0x100);
+ }
+ if(!strcmp(arg[i], "icon"))
+ {
+ Current->Icon = atoi(arg[i+1]);
+ }
+ }
+ }
+
+ else if(!strcmp(tag, "application") && !CurrentApplication)
+ {
+ if(Current->Apps)
+ {
+ CurrentApplication = Current->Apps;
+ while(CurrentApplication->Next)
+ CurrentApplication = CurrentApplication->Next;
+ CurrentApplication->Next = malloc(sizeof(struct Application));
+ memset(CurrentApplication->Next, 0, sizeof(struct Application));
+ CurrentApplication = CurrentApplication->Next;
+ }
+ else
+ {
+ Current->Apps = malloc(sizeof(struct Application));
+ memset(Current->Apps, 0, sizeof(struct Application));
+ CurrentApplication = Current->Apps;
+ }
+
+ int i;
+ for (i=0; arg[i]; i+=2)
+ {
+ if(!strcmp(arg[i], "name"))
+ {
+ MultiByteToWideChar(CP_ACP, 0, arg[i+1], -1, CurrentApplication->Name, 0x100);
+ }
+ }
+ }
+ else if (CurrentApplication)
+ {
+ strncpy(CurrentTag, tag, 0x100);
+ }
+ else
+ MessageBox(0,L"Invaild XML File1",0,0);
+}
+
+
+void text (void* usrdata, const char* data, int len)
+{
+ if (!CurrentApplication)
+ return;
+
+ // FIXME: handle newlines e.g. in Description
+ if(!strcmp(CurrentTag, "maintainer"))
+ {
+ int currentlengt = lstrlen(CurrentApplication->Location);
+ MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Maintainer[currentlengt], 0x100-currentlengt);
+ }
+ else if(!strcmp(CurrentTag, "description"))
+ {
+ int currentlengt = lstrlen(CurrentApplication->Description);
+ MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Description[currentlengt], 0x400-currentlengt);
+ }
+ else if(!strcmp(CurrentTag, "location"))
+ {
+ int currentlengt = lstrlen(CurrentApplication->Location);
+ MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Location[currentlengt], 0x100-currentlengt);
+ MessageBox(0,CurrentApplication->Location,0,0);
+ }
+}
+
+void tag_closed (void* tree, const char* tag)
+{
+ CurrentTag[0] = 0;
+
+ if(!strcmp(tag, "category"))
+ {
+ if (TagOpen)
+ {
+ TagOpen = FALSE;
+ }
+ else
+ {
+ Current = Current->Parent;
+ }
+ }
+ else if(!strcmp(tag, "application"))
+ {
+ CurrentApplication = NULL;
+ }
+}
+
+BOOL ProcessXML (const char* filename, struct Category* Root)
+{
+ int done = 0;
+ char buffer[255];
+
+ if(Current)
+ return FALSE;
+
+ Current = Root;
+ TagOpen = TRUE;
+
+ FILE* file = fopen(filename, "r");
+ if(!file)
+ {
+ MessageBox(0,L"Could not find the xml file !",0,0);
+ return FALSE;
+ }
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+ XML_SetElementHandler(parser, tag_opened, tag_closed);
+ XML_SetCharacterDataHandler(parser, text);
+
+ while (!done)
+ {
+ size_t len = fread (buffer, 1, sizeof(buffer), file);
+ done = len < sizeof(buffer);
+
+ buffer[len] = 0;
+ if(!XML_Parse(parser, buffer, len, done))
+ {
+ MessageBox(0,L"Could not parse the xml file !",0,0);
+ return FALSE;
+ }
+ }
+
+ XML_ParserFree(parser);
+ fclose(file);
+
+ return TRUE;
+}
+
+void FreeApps (struct Application* Apps)
+{
+ if (Apps->Next)
+ FreeApps(Apps->Next);
+
+ free(Apps);
+}
+
+void FreeTree (struct Category* Node)
+{
+ if (Node->Children)
+ FreeTree(Node->Children);
+
+ if (Node->Next)
+ FreeTree(Node->Next);
+
+ if (Node->Apps)
+ FreeApps(Node->Apps);
+
+ free(Node);
+}