/* PROJECT: ReactOS Downloader * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/downloader/xml.c * PURPOSE: Main program * PROGRAMMERS: Maarten Bosma, Lester Kortenhoeven */ #include #include #include #include #include #include #include #include "resources.h" #include "structures.h" HWND hwnd, hCategories, hApps, hDownloadButton, hUninstallButton, hUpdateButton, hHelpButton, hProfButton; HBITMAP hLogo, hUnderline; WCHAR* DescriptionHeadline = L""; WCHAR* DescriptionText = L""; WCHAR ApplicationText[700]; 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); WCHAR Strings [STRING_COUNT][MAX_STRING_LENGHT]; BOOL getUninstaller(WCHAR* RegName, WCHAR* Uninstaller) { const DWORD ArraySize = 200; HKEY hKey1; HKEY hKey2; DWORD Type = 0; DWORD Size = ArraySize; WCHAR Value[ArraySize]; WCHAR KeyName[ArraySize]; LONG i = 0; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",0,KEY_READ,&hKey1) == ERROR_SUCCESS) { while (RegEnumKeyExW(hKey1,i,KeyName,&Size,NULL,NULL,NULL,NULL) == ERROR_SUCCESS) { ++i; RegOpenKeyExW(hKey1,KeyName,0,KEY_READ,&hKey2); Size = ArraySize; if (RegQueryValueExW(hKey2,L"DisplayName",0,&Type,(LPBYTE)Value,&Size) == ERROR_SUCCESS) { Size = ArraySize; if (StrCmpW(Value,RegName) == 0) { if (RegQueryValueExW(hKey2,L"UninstallString",0,&Type,(LPBYTE)Uninstaller,&Size) == ERROR_SUCCESS) { RegCloseKey(hKey2); RegCloseKey(hKey1); return TRUE; } else { RegCloseKey(hKey2); RegCloseKey(hKey1); return FALSE; } } } RegCloseKey(hKey2); Size = ArraySize; } RegCloseKey(hKey1); } return FALSE; } void ShowMessage (WCHAR* title, WCHAR* message) { DescriptionHeadline = title; DescriptionText = message; InvalidateRect(hwnd,NULL,TRUE); UpdateWindow(hwnd); } void AddItems(HWND hwnd, struct Category* Category, struct Category* Parent) { TV_INSERTSTRUCTW Insert; Insert.item.lParam = (UINT)Category; Insert.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;; Insert.item.pszText = Category->Name; Insert.item.cchTextMax = lstrlenW(Category->Name); Insert.item.iImage = Category->Icon; Insert.item.iSelectedImage = Category->Icon; Insert.hInsertAfter = TVI_LAST; Insert.hParent = Category->Parent ? Category->Parent->TreeviewItem : TVI_ROOT; 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 CategoryChoosen(HWND hwnd, struct Category* Category) { struct Application* CurrentApplication; TV_INSERTSTRUCTW Insert; SelectedApplication = NULL; if(Category->Children && !Category->Apps) ShowMessage(Category->Name, Strings[IDS_CHOOSE_SUB]); else if(!Category->Children && Category->Apps) ShowMessage(Category->Name, Strings[IDS_CHOOSE_APP]); else if(Category->Children && Category->Apps) ShowMessage(Category->Name, Strings[IDS_CHOOSE_BOTH]); else ShowMessage(Category->Name, Strings[IDS_NO_APPS]); (void)TreeView_DeleteItem(hwnd, TVI_ROOT); (void)TreeView_DeleteItem(hwnd, TVI_ROOT); // Delete twice to bypass bug in windows Insert.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE; Insert.hInsertAfter = TVI_LAST; Insert.hParent = TVI_ROOT; CurrentApplication = Category->Apps; WCHAR Uninstaller[200]; while(CurrentApplication) { Insert.item.lParam = (UINT)CurrentApplication; Insert.item.pszText = CurrentApplication->Name; Insert.item.cchTextMax = lstrlenW(CurrentApplication->Name); Insert.item.iImage = 10; if(StrCmpW(CurrentApplication->RegName,L"")) { if(getUninstaller(CurrentApplication->RegName, Uninstaller)) Insert.item.iImage = 9; } SendMessage(hwnd, TVM_INSERTITEM, 0, (LPARAM)&Insert); CurrentApplication = CurrentApplication->Next; } } BOOL SetupControls (HWND hwnd) { TV_INSERTSTRUCTW Insert = {0}; HIMAGELIST hImageList; HINSTANCE hInstance = GetModuleHandle(NULL); WCHAR Cats[MAX_STRING_LENGHT], Apps[MAX_STRING_LENGHT]; TCHAR Buf[MAX_PATH]; char Tmp[MAX_PATH]; int i; // Getting downloader.xml path if(!GetSystemDirectory(Buf,sizeof(Buf)/sizeof(char))) return FALSE; lstrcat((LPTSTR)Buf, L"\\downloader.xml"); for (i = 0; i < _tcslen(Buf) + 1; i++) Tmp[i] = Buf[i]; // Parse the XML file if (!ProcessXML(Tmp, &Root)) return FALSE; LoadStringW(hInstance, IDS_CATS_TITLE, Cats, MAX_STRING_LENGHT); LoadStringW(hInstance, IDS_APPS_TITLE, Apps, MAX_STRING_LENGHT); // Set up the controls hCategories = CreateWindowExW(0, WC_TREEVIEWW, Cats, WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS, 0, 0, 0, 0, hwnd, NULL, hInstance, NULL); hApps = CreateWindowExW(0, WC_TREEVIEWW, Apps, WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS, 0, 0, 0, 0, hwnd, NULL, hInstance, NULL); hLogo = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_LOGO)); hUnderline = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_UNDERLINE)); hHelpButton = CreateWindowW(L"Button", L"", WS_CHILD | WS_VISIBLE | BS_ICON, 550, 10, 40, 40, hwnd, 0, hInstance, NULL); hUpdateButton = CreateWindowW(L"Button", L"", WS_CHILD | WS_VISIBLE | BS_ICON, 450, 10, 40, 40, hwnd, 0, hInstance, NULL); hProfButton = CreateWindowW(L"Button", L"", WS_CHILD | WS_VISIBLE | BS_ICON, 500, 10, 40, 40, hwnd, 0, hInstance, NULL); hDownloadButton = CreateWindowW(L"Button", L"", WS_CHILD | WS_VISIBLE | BS_BITMAP, 330, 505, 140, 33, hwnd, 0, hInstance, NULL); hUninstallButton = CreateWindowW(L"Button", L"", WS_CHILD | WS_VISIBLE | BS_BITMAP, 260, 505, 140, 33, hwnd, 0, hInstance, NULL); SendMessageW(hProfButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)(HANDLE)LoadIcon(hInstance,MAKEINTRESOURCE(IDI_PROF))); SendMessageW(hHelpButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)(HANDLE)LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELP))); SendMessageW(hUpdateButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)(HANDLE)LoadIcon(hInstance, MAKEINTRESOURCE(IDI_UPDATE))); SendMessageW(hDownloadButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DOWNLOAD))); SendMessageW(hUninstallButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_UNINSTALL))); ShowWindow(hUninstallButton, SW_HIDE); // Set deflaut entry for hApps Insert.item.mask = TVIF_TEXT|TVIF_IMAGE; Insert.item.pszText = Strings[IDS_CHOOSE_CATEGORY]; Insert.item.cchTextMax = lstrlenW(Strings[IDS_CHOOSE_CATEGORY]); Insert.item.iImage = 0; SendMessage(hApps, TVM_INSERTITEM, 0, (LPARAM)&Insert); // Create Tree Icons hImageList = ImageList_Create(16, 16, ILC_COLORDDB, 1, 1); SendMessageW(hCategories, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hImageList); SendMessageW(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); ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_9)), NULL); ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_10)), NULL); ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_11)), NULL); ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_12)), NULL); ImageList_Add(hImageList, LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TREEVIEW_ICON_13)), NULL); // Fill the TreeViews AddItems (hCategories, Root.Children, NULL); return TRUE; } 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 (HDC hdc, int x, int y, HBITMAP hBmp) { BITMAP bm; HDC hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBmp); GetObject(hBmp, sizeof(bm), &bm); TransparentBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, 0xFFFFFF); DeleteDC(hdcMem); } static void DrawDescription (HDC hdc, RECT DescriptionRect) { int i; HFONT Font; RECT Rect = {DescriptionRect.left+5, DescriptionRect.top+3, DescriptionRect.right-2, DescriptionRect.top+22}; // Backgroud Rectangle(hdc, DescriptionRect.left, DescriptionRect.top, DescriptionRect.right, DescriptionRect.bottom); // Underline for (i=DescriptionRect.left+1;iRegName, L"")) { if(getUninstaller(SelectedApplication->RegName, Uninstaller)) startUninstaller(Uninstaller); } } } else if (lParam == (LPARAM)hUpdateButton) { ShowMessage(Strings[IDS_UPDATE_TITLE], Strings[IDS_UPDATE]); } else if (lParam == (LPARAM)hHelpButton) { ShowMessage(Strings[IDS_HELP_TITLE], Strings[IDS_HELP]); } } } break; case WM_NOTIFY: { LPNMHDR data = (LPNMHDR)lParam; if(data->code == TVN_SELCHANGED) { BOOL bShowUninstaller = FALSE; if(data->hwndFrom == hCategories) { struct Category* Category = (struct Category*) ((LPNMTREEVIEW)lParam)->itemNew.lParam; CategoryChoosen (hApps, Category); } else if(data->hwndFrom == hApps) { SelectedApplication = (struct Application*) ((LPNMTREEVIEW)lParam)->itemNew.lParam; if(SelectedApplication) { ApplicationText[0]=L'\0'; if(StrCmpW(SelectedApplication->Version, L"")) { StrCatW(ApplicationText, Strings[IDS_VERSION]); StrCatW(ApplicationText, SelectedApplication->Version); StrCatW(ApplicationText, L"\n"); } if(StrCmpW(SelectedApplication->Licence, L"")) { StrCatW(ApplicationText, Strings[IDS_LICENCE]); StrCatW(ApplicationText, SelectedApplication->Licence); StrCatW(ApplicationText, L"\n"); } if(StrCmpW(SelectedApplication->Maintainer, L"")) { StrCatW(ApplicationText, Strings[IDS_MAINTAINER]); StrCatW(ApplicationText, SelectedApplication->Maintainer); StrCatW(ApplicationText, L"\n"); } if(StrCmpW(SelectedApplication->Licence, L"") || StrCmpW(SelectedApplication->Version, L"") || StrCmpW(SelectedApplication->Maintainer, L"")) StrCatW(ApplicationText, L"\n"); StrCatW(ApplicationText, SelectedApplication->Description); ShowMessage(SelectedApplication->Name, ApplicationText); WCHAR Uninstaller[200]; if(StrCmpW(SelectedApplication->RegName, L"")) { if(getUninstaller(SelectedApplication->RegName, Uninstaller)) { bShowUninstaller = TRUE; } } } } if (bShowUninstaller) showUninstaller(); else hideUninstaller(); } } break; case WM_SIZING: { LPRECT pRect = (LPRECT)lParam; if (pRect->right-pRect->left < 520) pRect->right = pRect->left + 520; if (pRect->bottom-pRect->top < 300) pRect->bottom = pRect->top + 300; } 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); RECT Rect = {Split_Vertical+5, Split_Hozizontal+5, LOWORD(lParam)-10, HIWORD(lParam)-50}; DescriptionRect = Rect; MoveWindow(hHelpButton, LOWORD(lParam)-50, 10, 40, 40, TRUE); MoveWindow(hUpdateButton, LOWORD(lParam)-150, 10, 40, 40, TRUE); MoveWindow(hProfButton, LOWORD(lParam)-100, 10, 40, 40, TRUE); if(IsWindowVisible(hUninstallButton)) MoveWindow(hDownloadButton, (Split_Vertical+LOWORD(lParam))/2, HIWORD(lParam)-45, 140, 35, TRUE); else MoveWindow(hDownloadButton, (Split_Vertical+LOWORD(lParam))/2-70, HIWORD(lParam)-45, 140, 35, TRUE); MoveWindow(hUninstallButton, (Split_Vertical+LOWORD(lParam))/2-140, HIWORD(lParam)-45, 140, 35, TRUE); } break; case WM_DESTROY: { DeleteObject(hLogo); if(Root.Children) FreeTree(Root.Children); PostQuitMessage(0); return 0; } break; } return DefWindowProc (hwnd, Message, wParam, lParam); } INT WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow) { int i; WNDCLASSEXW WndClass = {0}; MSG msg; InitCommonControls(); // Load strings for(i=0; i