| 1 | #include <atlbase.h>
|
|---|
| 2 | #include <objbase.h>
|
|---|
| 3 | #include <wininet.h>
|
|---|
| 4 | #include <fltk/Window.h>
|
|---|
| 5 | #include <fltk/Box.h>
|
|---|
| 6 | #include <fltk/Button.h>
|
|---|
| 7 | #include <fltk/Font.h>
|
|---|
| 8 | #include <fltk/Input.h>
|
|---|
| 9 | #include <fltk/win32.h>
|
|---|
| 10 | #include <fltk/cursor.h>
|
|---|
| 11 | #include <fltk/events.h>
|
|---|
| 12 | #include <fltk/run.h>
|
|---|
| 13 |
|
|---|
| 14 | #include <windows.h>
|
|---|
| 15 | #include <stdio.h>
|
|---|
| 16 | #include <stdlib.h>
|
|---|
| 17 | #include "resource.h"
|
|---|
| 18 |
|
|---|
| 19 | #pragma comment(lib, "atl.lib")
|
|---|
| 20 | #pragma comment(lib, "user32.lib")
|
|---|
| 21 | #pragma comment(lib, "ws2_32.lib")
|
|---|
| 22 | #pragma comment(lib, "wininet.lib")
|
|---|
| 23 | #pragma comment(lib, "gdi32.lib")
|
|---|
| 24 | #pragma comment(lib, "shell32.lib")
|
|---|
| 25 | #ifndef _DEBUG
|
|---|
| 26 | # pragma comment(lib, "msvcrt.lib")
|
|---|
| 27 | # pragma comment(linker, "/nodefaultlib:libc.lib")
|
|---|
| 28 | # pragma comment(linker, "/opt:noref")
|
|---|
| 29 | #endif
|
|---|
| 30 | #ifndef ATLAXWIN_CLASS
|
|---|
| 31 | # define ATLAXWIN_CLASS "AtlAxWin"
|
|---|
| 32 | #endif
|
|---|
| 33 |
|
|---|
| 34 | /**
|
|---|
| 35 | * fltk::ActiveX class
|
|---|
| 36 | */
|
|---|
| 37 | namespace fltk {
|
|---|
| 38 | class ActiveX : public Widget {
|
|---|
| 39 | private:
|
|---|
| 40 | HWND hWnd;
|
|---|
| 41 | IDispatch* pDispatch;
|
|---|
| 42 |
|
|---|
| 43 | public:
|
|---|
| 44 | /**
|
|---|
| 45 | * handle messages
|
|---|
| 46 | */
|
|---|
| 47 | int handle(int e) {
|
|---|
| 48 | fltk::Window* parent = this->window();
|
|---|
| 49 | long style;
|
|---|
| 50 | switch (e) {
|
|---|
| 51 | case fltk::SHOW:
|
|---|
| 52 | SetParent(hWnd, fltk::xid(parent));
|
|---|
| 53 | ShowWindow(hWnd, SW_SHOW);
|
|---|
| 54 | style = GetWindowLong(hWnd, GWL_STYLE);
|
|---|
| 55 | SetWindowLong(hWnd, GWL_STYLE, (style | WS_CHILD) & ~WS_POPUP);
|
|---|
| 56 | break;
|
|---|
| 57 | }
|
|---|
| 58 | return 0;
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | /**
|
|---|
| 62 | * re-layout callback function
|
|---|
| 63 | */
|
|---|
| 64 | void layout() {
|
|---|
| 65 | fltk::Window* parent = this->window();
|
|---|
| 66 | if (parent && parent->shown()) {
|
|---|
| 67 | SetWindowPos(hWnd,
|
|---|
| 68 | NULL,
|
|---|
| 69 | x(), y(), w(), h(),
|
|---|
| 70 | SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|---|
| 71 | UpdateWindow(hWnd);
|
|---|
| 72 | }
|
|---|
| 73 | Widget::layout();
|
|---|
| 74 | }
|
|---|
| 75 |
|
|---|
| 76 | /**
|
|---|
| 77 | * constructor, create ATL window amd get dispatch object.
|
|---|
| 78 | */
|
|---|
| 79 | ActiveX(int x, int y, int w, int h, const char *l) : Widget(x,y,w,h,l) {
|
|---|
| 80 | hWnd = CreateWindowEx(
|
|---|
| 81 | WS_EX_TOOLWINDOW,
|
|---|
| 82 | ATLAXWIN_CLASS,
|
|---|
| 83 | l,
|
|---|
| 84 | WS_POPUP,
|
|---|
| 85 | x, y, w, h,
|
|---|
| 86 | NULL,
|
|---|
| 87 | (HMENU)0,
|
|---|
| 88 | GetModuleHandle(NULL),
|
|---|
| 89 | NULL);
|
|---|
| 90 | pDispatch = NULL;
|
|---|
| 91 | if (hWnd) {
|
|---|
| 92 | IUnknown* pUnknown = NULL;
|
|---|
| 93 | HRESULT hr = AtlAxGetControl(hWnd, &pUnknown);
|
|---|
| 94 | if (pUnknown) pUnknown->QueryInterface(&pDispatch);
|
|---|
| 95 | if (!pDispatch) pUnknown->Release();
|
|---|
| 96 | }
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | /**
|
|---|
| 100 | * destructor, release dispatch object and destroy window.
|
|---|
| 101 | */
|
|---|
| 102 | ~ActiveX() {
|
|---|
| 103 | if (pDispatch)
|
|---|
| 104 | pDispatch->Release();
|
|---|
| 105 | DestroyWindow(hWnd);
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | /**
|
|---|
| 109 | * getter of dispatch object
|
|---|
| 110 | */
|
|---|
| 111 | IDispatch* getIDispatch() {
|
|---|
| 112 | return pDispatch;
|
|---|
| 113 | }
|
|---|
| 114 | };
|
|---|
| 115 | }
|
|---|
| 116 |
|
|---|
| 117 | /**
|
|---|
| 118 | * get usc file from html
|
|---|
| 119 | */
|
|---|
| 120 | BOOL GetUscFileName(const char* pszChannel, char *pszUscFileName)
|
|---|
| 121 | {
|
|---|
| 122 | HINTERNET hSession = 0;
|
|---|
| 123 | HINTERNET hConnect = 0;
|
|---|
| 124 | HINTERNET hRequest = 0;
|
|---|
| 125 | char szBuf[1000];
|
|---|
| 126 | char szUrl[2000];
|
|---|
| 127 | DWORD dwSize = 0;
|
|---|
| 128 | DWORD dwIndex = 0;
|
|---|
| 129 | DWORD dwContentLength = (DWORD)-1;
|
|---|
| 130 | DWORD dwStatusCode = 200;
|
|---|
| 131 | char *pszHtml = NULL;
|
|---|
| 132 | char *pszUscUrl = NULL;
|
|---|
| 133 | BOOL bRet = FALSE;
|
|---|
| 134 |
|
|---|
| 135 | _snprintf(szUrl, sizeof(szUrl)-1, "/channel/%s", pszChannel);
|
|---|
| 136 |
|
|---|
| 137 | hSession = InternetOpen(
|
|---|
| 138 | "UstreamPlayer",
|
|---|
| 139 | INTERNET_OPEN_TYPE_PRECONFIG,
|
|---|
| 140 | NULL,
|
|---|
| 141 | NULL,
|
|---|
| 142 | 0);
|
|---|
| 143 | if (hSession == NULL) goto leave;
|
|---|
| 144 |
|
|---|
| 145 | hConnect = InternetConnect(
|
|---|
| 146 | hSession,
|
|---|
| 147 | "ustream.tv",
|
|---|
| 148 | 80,
|
|---|
| 149 | NULL,
|
|---|
| 150 | NULL,
|
|---|
| 151 | INTERNET_SERVICE_HTTP,
|
|---|
| 152 | 0,
|
|---|
| 153 | 0);
|
|---|
| 154 | if (hConnect == NULL) goto leave;
|
|---|
| 155 |
|
|---|
| 156 | hRequest = HttpOpenRequest(
|
|---|
| 157 | hConnect,
|
|---|
| 158 | "GET",
|
|---|
| 159 | szUrl,
|
|---|
| 160 | NULL,
|
|---|
| 161 | NULL,
|
|---|
| 162 | NULL,
|
|---|
| 163 | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD,
|
|---|
| 164 | 0);
|
|---|
| 165 | if (hConnect == NULL) goto leave;
|
|---|
| 166 |
|
|---|
| 167 | if (HttpSendRequest(
|
|---|
| 168 | hRequest,
|
|---|
| 169 | NULL,
|
|---|
| 170 | 0,
|
|---|
| 171 | NULL,
|
|---|
| 172 | 0) == FALSE) goto leave;
|
|---|
| 173 |
|
|---|
| 174 | szBuf[0] = 0;
|
|---|
| 175 | dwSize = sizeof(szBuf)-1;
|
|---|
| 176 | if (HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH, &szBuf, &dwSize, &dwIndex) == TRUE) {
|
|---|
| 177 | dwContentLength = atol(szBuf);
|
|---|
| 178 | }
|
|---|
| 179 |
|
|---|
| 180 | if (dwStatusCode == 200 || dwStatusCode == 201) {
|
|---|
| 181 | for (;;) {
|
|---|
| 182 | dwSize = sizeof(szBuf)-1;
|
|---|
| 183 | if (InternetReadFile(
|
|---|
| 184 | hRequest,
|
|---|
| 185 | szBuf,
|
|---|
| 186 | dwSize,
|
|---|
| 187 | &dwSize) == FALSE) break;
|
|---|
| 188 | if (dwSize <= 0) break;
|
|---|
| 189 | szBuf[dwSize] = 0;
|
|---|
| 190 | if (!pszHtml) {
|
|---|
| 191 | pszHtml = (char*)malloc(dwSize+1);
|
|---|
| 192 | *pszHtml = '\0';
|
|---|
| 193 | } else {
|
|---|
| 194 | pszHtml = (char*)realloc(pszHtml, strlen(pszHtml)+dwSize+1);
|
|---|
| 195 | }
|
|---|
| 196 | strcat(pszHtml, szBuf);
|
|---|
| 197 | if (strlen(pszHtml) > dwContentLength)
|
|---|
| 198 | break;
|
|---|
| 199 | }
|
|---|
| 200 |
|
|---|
| 201 | if (pszHtml) {
|
|---|
| 202 | pszUscUrl = strstr(pszHtml, ".usc"");
|
|---|
| 203 | if (pszUscUrl) {
|
|---|
| 204 | *(pszUscUrl+4) = '\0';
|
|---|
| 205 | while(pszUscUrl-- > pszHtml) {
|
|---|
| 206 | if (!strncmp(pszUscUrl, "http://", 7))
|
|---|
| 207 | break;
|
|---|
| 208 | }
|
|---|
| 209 | if (pszUscUrl > pszHtml) {
|
|---|
| 210 | strcpy(pszUscFileName, pszUscUrl);
|
|---|
| 211 | bRet = TRUE;
|
|---|
| 212 | }
|
|---|
| 213 | }
|
|---|
| 214 | free(pszHtml);
|
|---|
| 215 | }
|
|---|
| 216 | }
|
|---|
| 217 |
|
|---|
| 218 | leave:
|
|---|
| 219 | InternetCloseHandle(hRequest);
|
|---|
| 220 | InternetCloseHandle(hConnect);
|
|---|
| 221 | InternetCloseHandle(hSession);
|
|---|
| 222 | return bRet;
|
|---|
| 223 | }
|
|---|
| 224 |
|
|---|
| 225 | /**
|
|---|
| 226 | * callback function of input box.
|
|---|
| 227 | */
|
|---|
| 228 | void enter_cb(fltk::Widget *w, void* data) {
|
|---|
| 229 | fltk::Input* input = (fltk::Input*)w;
|
|---|
| 230 | fltk::Window* parent = input->window();
|
|---|
| 231 | fltk::ActiveX* ocx = (fltk::ActiveX*)data;
|
|---|
| 232 | IDispatch* pDispatch = ocx->getIDispatch();
|
|---|
| 233 | if (pDispatch) {
|
|---|
| 234 | USES_CONVERSION;
|
|---|
| 235 | char szUscFileName[2048] = {0};
|
|---|
| 236 |
|
|---|
| 237 | parent->cursor(fltk::CURSOR_WAIT);
|
|---|
| 238 |
|
|---|
| 239 | if (!GetUscFileName(input->value(), szUscFileName)) {
|
|---|
| 240 | parent->cursor(fltk::CURSOR_DEFAULT);
|
|---|
| 241 | return;
|
|---|
| 242 | }
|
|---|
| 243 |
|
|---|
| 244 | DISPID dispid = 0;
|
|---|
| 245 | OLECHAR* ole_name = A2OLE("LoadMovie");
|
|---|
| 246 | HRESULT hr = pDispatch->GetIDsOfNames(IID_NULL, &ole_name, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
|
|---|
| 247 | if (FAILED(hr)) {
|
|---|
| 248 | parent->cursor(fltk::CURSOR_DEFAULT);
|
|---|
| 249 | return;
|
|---|
| 250 | }
|
|---|
| 251 | VARIANTARG vargs[2];
|
|---|
| 252 | VariantInit(&vargs[0]);
|
|---|
| 253 | V_VT(&vargs[0]) = VT_BSTR;
|
|---|
| 254 | V_BSTR(&vargs[0]) = A2BSTR(szUscFileName);
|
|---|
| 255 | VariantInit(&vargs[1]);
|
|---|
| 256 | V_VT(&vargs[1]) = VT_I4;
|
|---|
| 257 | V_I4(&vargs[1]) = 0;
|
|---|
| 258 | DISPPARAMS param = {vargs, NULL, 2, 0};
|
|---|
| 259 | VARIANT result;
|
|---|
| 260 | VariantInit(&result);
|
|---|
| 261 | hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
|
|---|
| 262 | ¶m, &result, NULL, NULL);
|
|---|
| 263 | parent->cursor(fltk::CURSOR_DEFAULT);
|
|---|
| 264 | }
|
|---|
| 265 | }
|
|---|
| 266 |
|
|---|
| 267 | /**
|
|---|
| 268 | * set window icon from resource number.
|
|---|
| 269 | */
|
|---|
| 270 | BOOL SetWindowIcon(HWND hWnd, UINT uID)
|
|---|
| 271 | {
|
|---|
| 272 | BOOL bRetVal = FALSE;
|
|---|
| 273 | if (IsWindow(hWnd)) {
|
|---|
| 274 | HINSTANCE hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
|
|---|
| 275 | HICON hIconSmall = (HICON)LoadImage(hInst, MAKEINTRESOURCE(uID), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
|---|
| 276 | if (hIconSmall)
|
|---|
| 277 | SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall);
|
|---|
| 278 | printf("%d\n", hIconSmall);
|
|---|
| 279 | HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(uID));
|
|---|
| 280 | if (hIcon)
|
|---|
| 281 | SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
|---|
| 282 | printf("%d\n", hIcon);
|
|---|
| 283 | bRetVal = TRUE;
|
|---|
| 284 | }
|
|---|
| 285 | return bRetVal;
|
|---|
| 286 | }
|
|---|
| 287 |
|
|---|
| 288 | /**
|
|---|
| 289 | * WinMain
|
|---|
| 290 | */
|
|---|
| 291 | int WINAPI WinMain(
|
|---|
| 292 | HINSTANCE hInstance,
|
|---|
| 293 | HINSTANCE hPrevInstance,
|
|---|
| 294 | LPSTR lpCmdLine,
|
|---|
| 295 | int nCmdShow) {
|
|---|
| 296 |
|
|---|
| 297 | int w = 300, h = 300;
|
|---|
| 298 |
|
|---|
| 299 | AtlAxWinInit();
|
|---|
| 300 |
|
|---|
| 301 | fltk::Window* window = new fltk::Window(w, h, "UstreamPlayer");
|
|---|
| 302 | window->begin();
|
|---|
| 303 | fltk::ActiveX* ocx = new fltk::ActiveX(
|
|---|
| 304 | 0, 0, w, h-20, "ShockwaveFlash.ShockwaveFlash");
|
|---|
| 305 | fltk::Input* input = new fltk::Input(0, h-20, w, 20);
|
|---|
| 306 | input->textfont(input->textfont()->bold());
|
|---|
| 307 | input->when(fltk::WHEN_ENTER_KEY);
|
|---|
| 308 | input->callback(enter_cb, ocx);
|
|---|
| 309 | window->resizable(ocx);
|
|---|
| 310 | window->end();
|
|---|
| 311 | window->show();
|
|---|
| 312 |
|
|---|
| 313 | SetWindowIcon(fltk::xid(window), IDR_ICONMAIN);
|
|---|
| 314 |
|
|---|
| 315 | return fltk::run();
|
|---|
| 316 | }
|
|---|