mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 05:02:56 +00:00
[RAPPS] snapshot url support (#2925)
* [RAPPS] add snapshot url support * [RAPPS] fix snapshot prev window won't update if size not changed * [RAPPS] fix crash after cancel download * [RAPPS] show broken-img if failed to create file / make network request * [RAPPS] create a snapshots folder if it does not exist * [RAPPS] add a helper function to perform callback * [RAPPS] check bIsCancelled when handling ERROR_INVALID_HANDLE * [RAPPS] remove W suffix for AsyncInetDownload * [RAPPS] add assert for unknown event * [RAPPS] Improve AsyncInetDownload error handling * [RAPPS] move DisplayFailed to private, fix crash when cancelling * [RAPPS] check for ERROR_INTERNET_OPERATION_CANCELLED * [RAPPS] improve error logging * [RAPPS] remove \r in error logging * [RAPPS] rewrite AsyncInet
This commit is contained in:
parent
fbf119fde1
commit
e506581454
6 changed files with 735 additions and 40 deletions
|
@ -11,6 +11,7 @@
|
|||
#include "rapps.h"
|
||||
#include "rosui.h"
|
||||
#include "crichedit.h"
|
||||
#include "asyncinet.h"
|
||||
|
||||
#include <shlobj_undoc.h>
|
||||
#include <shlguid_undoc.h>
|
||||
|
@ -43,11 +44,16 @@ using namespace Gdiplus;
|
|||
// minimum width of richedit
|
||||
#define RICHEDIT_MIN_WIDTH 160
|
||||
|
||||
|
||||
// user-defined window message
|
||||
#define WM_RAPPS_DOWNLOAD_COMPLETE (WM_USER + 1) // notify download complete. wParam is error code, and lParam is a pointer to SnapshotDownloadParam
|
||||
#define WM_RAPPS_RESIZE_CHILDREN (WM_USER + 2) // ask parent window to resize children.
|
||||
|
||||
enum SNPSHT_STATUS
|
||||
{
|
||||
SNPSHTPREV_EMPTY, // show nothing
|
||||
SNPSHTPREV_LOADING, // image is loading (most likely downloading)
|
||||
SNPSHTPREV_FILE, // display image from a file
|
||||
SNPSHTPREV_IMAGE, // display image from a file
|
||||
SNPSHTPREV_FAILED // image can not be shown (download failure or wrong image)
|
||||
};
|
||||
|
||||
|
@ -59,6 +65,14 @@ enum SNPSHT_STATUS
|
|||
|
||||
#define PI 3.1415927
|
||||
|
||||
typedef struct __SnapshotDownloadParam
|
||||
{
|
||||
LONGLONG ID;
|
||||
HANDLE hFile;
|
||||
HWND hwndNotify;
|
||||
ATL::CStringW DownloadFileName;
|
||||
} SnapshotDownloadParam;
|
||||
|
||||
INT GetSystemColorDepth()
|
||||
{
|
||||
DEVMODEW pDevMode;
|
||||
|
@ -290,6 +304,40 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
int SnapshotDownloadCallback(
|
||||
pASYNCINET AsyncInet,
|
||||
ASYNC_EVENT Event,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
VOID* Extension
|
||||
)
|
||||
{
|
||||
SnapshotDownloadParam* DownloadParam = (SnapshotDownloadParam*)Extension;
|
||||
switch (Event)
|
||||
{
|
||||
case ASYNCINET_DATA:
|
||||
DWORD BytesWritten;
|
||||
WriteFile(DownloadParam->hFile, (LPCVOID)wParam, (DWORD)lParam, &BytesWritten, NULL);
|
||||
break;
|
||||
case ASYNCINET_COMPLETE:
|
||||
CloseHandle(DownloadParam->hFile);
|
||||
SendMessage(DownloadParam->hwndNotify, WM_RAPPS_DOWNLOAD_COMPLETE, (WPARAM)ERROR_SUCCESS, (LPARAM)DownloadParam);
|
||||
break;
|
||||
case ASYNCINET_CANCELLED:
|
||||
CloseHandle(DownloadParam->hFile);
|
||||
SendMessage(DownloadParam->hwndNotify, WM_RAPPS_DOWNLOAD_COMPLETE, (WPARAM)ERROR_CANCELLED, (LPARAM)DownloadParam);
|
||||
break;
|
||||
case ASYNCINET_ERROR:
|
||||
CloseHandle(DownloadParam->hFile);
|
||||
SendMessage(DownloadParam->hwndNotify, WM_RAPPS_DOWNLOAD_COMPLETE, wParam, (LPARAM)DownloadParam);
|
||||
break;
|
||||
default:
|
||||
ATLASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class CAppSnapshotPreview :
|
||||
public CWindowImpl<CAppSnapshotPreview>
|
||||
{
|
||||
|
@ -301,6 +349,9 @@ private:
|
|||
BOOL bLoadingTimerOn = FALSE;
|
||||
int LoadingAnimationFrame = 0;
|
||||
int BrokenImgSize = BROKENIMG_ICON_SIZE;
|
||||
pASYNCINET AsyncInet = NULL;
|
||||
LONGLONG ContentID = 0; // used to determine whether image has been switched when download complete. Increase by 1 each time the content of this window changed
|
||||
ATL::CStringW TempImagePath; // currently displayed temp file
|
||||
|
||||
BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId)
|
||||
{
|
||||
|
@ -324,6 +375,42 @@ private:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case WM_RAPPS_DOWNLOAD_COMPLETE:
|
||||
{
|
||||
SnapshotDownloadParam* DownloadParam = (SnapshotDownloadParam*)lParam;
|
||||
AsyncInetRelease(AsyncInet);
|
||||
AsyncInet = NULL;
|
||||
switch (wParam)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
if (ContentID == DownloadParam->ID)
|
||||
{
|
||||
DisplayFile(DownloadParam->DownloadFileName);
|
||||
// send a message to trigger resizing
|
||||
::SendMessageW(::GetParent(m_hWnd), WM_RAPPS_RESIZE_CHILDREN, 0, 0);
|
||||
InvalidateRect(0, 0);
|
||||
TempImagePath = DownloadParam->DownloadFileName; // record tmp file path in order to delete it when cleanup
|
||||
}
|
||||
else
|
||||
{
|
||||
// the picture downloaded is already outdated. delete it.
|
||||
DeleteFileW(DownloadParam->DownloadFileName);
|
||||
}
|
||||
break;
|
||||
case ERROR_CANCELLED:
|
||||
DeleteFileW(DownloadParam->DownloadFileName);
|
||||
break;
|
||||
default:
|
||||
DisplayFailed();
|
||||
// send a message to trigger resizing
|
||||
::SendMessageW(::GetParent(m_hWnd), WM_RAPPS_RESIZE_CHILDREN, 0, 0);
|
||||
InvalidateRect(0, 0);
|
||||
DeleteFileW(DownloadParam->DownloadFileName);
|
||||
break;
|
||||
}
|
||||
delete DownloadParam;
|
||||
break;
|
||||
}
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
|
@ -388,6 +475,38 @@ private:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
VOID DisplayLoading()
|
||||
{
|
||||
SetStatus(SNPSHTPREV_LOADING);
|
||||
if (bLoadingTimerOn)
|
||||
{
|
||||
KillTimer(TIMER_LOADING_ANIMATION);
|
||||
}
|
||||
LoadingAnimationFrame = 0;
|
||||
bLoadingTimerOn = TRUE;
|
||||
SetTimer(TIMER_LOADING_ANIMATION, 1000 / LOADING_ANIMATION_FPS, 0);
|
||||
}
|
||||
|
||||
VOID DisplayFailed()
|
||||
{
|
||||
InterlockedIncrement64(&ContentID);
|
||||
SetStatus(SNPSHTPREV_FAILED);
|
||||
PreviousDisplayCleanup();
|
||||
}
|
||||
|
||||
BOOL DisplayFile(LPCWSTR lpszFileName)
|
||||
{
|
||||
PreviousDisplayCleanup();
|
||||
SetStatus(SNPSHTPREV_IMAGE);
|
||||
pImage = Bitmap::FromFile(lpszFileName, 0);
|
||||
if (pImage->GetLastStatus() != Ok)
|
||||
{
|
||||
DisplayFailed();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID SetStatus(SNPSHT_STATUS Status)
|
||||
{
|
||||
SnpshtPrevStauts = Status;
|
||||
|
@ -445,7 +564,7 @@ private:
|
|||
}
|
||||
break;
|
||||
|
||||
case SNPSHTPREV_FILE:
|
||||
case SNPSHTPREV_IMAGE:
|
||||
{
|
||||
if (pImage)
|
||||
{
|
||||
|
@ -541,39 +660,82 @@ public:
|
|||
delete pImage;
|
||||
pImage = NULL;
|
||||
}
|
||||
if (AsyncInet)
|
||||
{
|
||||
AsyncInetCancel(AsyncInet);
|
||||
}
|
||||
if (!TempImagePath.IsEmpty())
|
||||
{
|
||||
DeleteFileW(TempImagePath.GetString());
|
||||
TempImagePath.Empty();
|
||||
}
|
||||
}
|
||||
|
||||
VOID DisplayEmpty()
|
||||
{
|
||||
InterlockedIncrement64(&ContentID);
|
||||
SetStatus(SNPSHTPREV_EMPTY);
|
||||
PreviousDisplayCleanup();
|
||||
}
|
||||
|
||||
VOID DisplayLoading()
|
||||
BOOL DisplayImage(LPCWSTR lpszLocation)
|
||||
{
|
||||
SetStatus(SNPSHTPREV_LOADING);
|
||||
LONGLONG ID = InterlockedIncrement64(&ContentID);
|
||||
PreviousDisplayCleanup();
|
||||
bLoadingTimerOn = TRUE;
|
||||
SetTimer(TIMER_LOADING_ANIMATION, 1000 / LOADING_ANIMATION_FPS, 0);
|
||||
}
|
||||
|
||||
BOOL DisplayFile(LPCWSTR lpszFileName)
|
||||
{
|
||||
SetStatus(SNPSHTPREV_FILE);
|
||||
PreviousDisplayCleanup();
|
||||
pImage = Bitmap::FromFile(lpszFileName, 0);
|
||||
if (pImage->GetLastStatus() != Ok)
|
||||
if (PathIsURLW(lpszLocation))
|
||||
{
|
||||
DisplayFailed();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
DisplayLoading();
|
||||
|
||||
VOID DisplayFailed()
|
||||
{
|
||||
SetStatus(SNPSHTPREV_FAILED);
|
||||
PreviousDisplayCleanup();
|
||||
SnapshotDownloadParam* DownloadParam = new SnapshotDownloadParam;
|
||||
if (!DownloadParam) return FALSE;
|
||||
|
||||
DownloadParam->hwndNotify = m_hWnd;
|
||||
DownloadParam->ID = ID;
|
||||
// generate a filename
|
||||
ATL::CStringW SnapshotFolder = CAvailableApps::m_Strings.szAppsPath;
|
||||
PathAppendW(SnapshotFolder.GetBuffer(MAX_PATH), L"snapshots");
|
||||
SnapshotFolder.ReleaseBuffer();
|
||||
|
||||
if (!PathIsDirectoryW(SnapshotFolder.GetString()))
|
||||
{
|
||||
CreateDirectoryW(SnapshotFolder.GetString(), NULL);
|
||||
}
|
||||
|
||||
if (!GetTempFileNameW(SnapshotFolder.GetString(), L"img",
|
||||
0, DownloadParam->DownloadFileName.GetBuffer(MAX_PATH)))
|
||||
{
|
||||
DownloadParam->DownloadFileName.ReleaseBuffer();
|
||||
delete DownloadParam;
|
||||
DisplayFailed();
|
||||
return FALSE;
|
||||
}
|
||||
DownloadParam->DownloadFileName.ReleaseBuffer();
|
||||
|
||||
DownloadParam->hFile = CreateFileW(DownloadParam->DownloadFileName.GetString(),
|
||||
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (DownloadParam->hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
delete DownloadParam;
|
||||
DisplayFailed();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
AsyncInet = AsyncInetDownload(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, lpszLocation, TRUE, SnapshotDownloadCallback, DownloadParam);
|
||||
if (!AsyncInet)
|
||||
{
|
||||
CloseHandle(DownloadParam->hFile);
|
||||
DeleteFileW(DownloadParam->DownloadFileName.GetBuffer());
|
||||
delete DownloadParam;
|
||||
DisplayFailed();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DisplayFile(lpszLocation);
|
||||
}
|
||||
}
|
||||
|
||||
int GetRequestedWidth(int Height) // calculate requested window width by given height
|
||||
|
@ -584,7 +746,7 @@ public:
|
|||
return 0;
|
||||
case SNPSHTPREV_LOADING:
|
||||
return 200;
|
||||
case SNPSHTPREV_FILE:
|
||||
case SNPSHTPREV_IMAGE:
|
||||
if (pImage)
|
||||
{
|
||||
// return the width needed to display image inside the window.
|
||||
|
@ -631,6 +793,11 @@ private:
|
|||
ResizeChildren(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
}
|
||||
case WM_RAPPS_RESIZE_CHILDREN:
|
||||
{
|
||||
ResizeChildren();
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
{
|
||||
OnCommand(wParam, lParam);
|
||||
|
@ -777,10 +944,10 @@ public:
|
|||
|
||||
BOOL ShowAvailableAppInfo(CAvailableApplicationInfo* Info)
|
||||
{
|
||||
ATL::CStringW SnapshotFilename;
|
||||
if (Info->RetrieveSnapshot(0, SnapshotFilename))
|
||||
ATL::CStringW SnapshotLocation;
|
||||
if (Info->RetrieveSnapshot(0, SnapshotLocation))
|
||||
{
|
||||
SnpshtPrev->DisplayFile(SnapshotFilename);
|
||||
SnpshtPrev->DisplayImage(SnapshotLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue