Euhm... I can't try this idea, because I receive only:
- string path
- Stream output
- bool close
- ref bool handled
in "OnLoadExternalResourceBy*Path". I should also recieve request type and post data in that method. To make everything clear, I made some dummy code:
steps:
- first: receive "OnLoadExternalResourceBy*Path", those methods both call: "LoadExternalResource". "LoadExternalResource" stores some info.
- second: receive "OnSendData". store the post data.
- third: receive "OnGetBindInfo": check if it is POST or GET and fill the info.Output stream, based on all the info (which doesn't work).
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace Not.Working
{
public enum RequestType { UNKNOWN = 0x00, GET = 0x01, POST = 0x02 };
public partial class FlashControl : UserControl
{
internal delegate Int32 GetBindInfoHandler(UInt32 hFPC, ref Int32 grfBINDF, ref BINDINFO pbindinfo, Int32 lParam);
[DllImport("f_in_box.dll", EntryPoint = "FPC_AddGetBindInfoHandler", CallingConvention = CallingConvention.StdCall)]
internal static extern Int32 FPC_AddGetBindInfoHandler(UInt32 hFPC, GetBindInfoHandler pGetBindInfoHandler, Int32 lParam);
[DllImport("f_in_box.dll", EntryPoint = "FPC_RemoveGetBindInfoHandler", CallingConvention = CallingConvention.StdCall)]
internal static extern Int32 FPC_RemoveGetBindInfoHandler(UInt32 hFPC, Int32 dwCookie);
public event ExternalInterfaceCallEventHandler OnExternalInterfaceCall;
public event ExternalResourceLoaderEventHandler OnExternalResourceLoader;
[StructLayout(LayoutKind.Sequential)]
internal struct STGMEDIUM
{
public Int32 tymed;
public Int32 hGlobal;
public Int32 pUnkForRelease;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SECURITY_ATTRIBUTES
{
public Int32 nLength;
public Int32 lpSecurityDescriptor;
public Int32 bInheritHandle;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BINDINFO
{
public Int32 cbSize;
public Int32 szExtraInfo;
public STGMEDIUM stgmedData;
public Int32 grfBindInfoF;
public Int32 dwBindVerb;
public Int32 szCustomVerb;
public Int32 cbstgmedData;
public Int32 dwOptions;
public Int32 dwOptionsFlags;
public Int32 dwCodePage;
public SECURITY_ATTRIBUTES securityAttributes;
public Guid iid;
public Int32 pUnk;
public Int32 dwReserved;
}
private f_in_box__lib.f_in_box__control flashCtl;
private ServiceCallInfo info;
public FlashControl(string context)
{
InitializeComponent();
// loads flash player from resource
Stream stream = new MemoryStream(Properties.Resources.FILE_FLASH);
flashCtl = new f_in_box__lib.f_in_box__control(new f_in_box__lib.AxCode(stream));
Controls.Add(flashCtl);
// configure the control
flashCtl.Context = context;
flashCtl.StandardMenu = false;
flashCtl.TransparentMode = true;
flashCtl.FlashProperty_BackgroundColor = -1;
flashCtl.FlashProperty_Base = "";
flashCtl.FlashProperty_BGColor = "";
flashCtl.FlashProperty_WMode = "Transparent";
flashCtl.FlashProperty_ScaleMode = 3;
flashCtl.FlashProperty_Quality = 1;
flashCtl.FlashProperty_Menu = true;
flashCtl.FlashProperty_AlignMode = 0;
flashCtl.AxCode.SoundEnabled = true;
flashCtl.AxCode.OnSendData += new f_in_box__lib.AxCode.OnSendDataHandler(AxCode_OnSendData);
flashCtl.AxCode.OnLoadExternalResourceByFullPath += new f_in_box__lib.AxCode.OnLoadExternalResourceByFullPathEventHandler(flashCtl_OnLoadExternalResourceByFullPath);
flashCtl.OnLoadExternalResourceByRelativePath += new f_in_box__lib.f_in_box__control.OnLoadExternalResourceByRelativePathEventHandler(flashCtl_OnLoadExternalResourceByRelativePath);
// handler to check if it is post or get
FPC_AddGetBindInfoHandler(flashCtl.AxCode.Handle, new GetBindInfoHandler(flashCtl_OnGetBindInfo), 0);
}
private Int32 flashCtl_OnGetBindInfo(UInt32 hFPC, ref Int32 grfBINDF, ref BINDINFO pbindinfo, Int32 lParam)
{
RequestType type = RequestType.UNKNOWN;
// get
if (pbindinfo.dwBindVerb == 0)
{
type = RequestType.GET;
}
// post
else if (pbindinfo.dwBindVerb == 1)
{
type = RequestType.POST;
}
// finally I receive this event.
// Now, I know everything I need to know to complete the request.
// the problem is that it doesn't work.
// If I fill the "info.Output" here, I don't receive a thing in flash.
return 0;
}
private void AxCode_OnSendData(object sender, byte[] buffer)
{
info.Post = buffer;
// At this moment I know the post data, but I still don't know if it is POST or GET,
// So again, I store the post data into the "ServiceCallInfo" object
}
private void flashCtl_OnLoadExternalResourceByRelativePath(object sender, string path, Stream stream, ref bool handled)
{
LoadExternalResource(path, stream, ref handled, true);
}
private void flashCtl_OnLoadExternalResourceByFullPath(object sender, string path, Stream stream, ref bool handled)
{
LoadExternalResource(path, stream, ref handled, false);
}
private void LoadExternalResource(string path, Stream stream, ref bool handled, bool relative)
{
info = new ServiceCallInfo();
info.Relative = relative;
info.Handled = handled;
info.Path = path;
info.Output = stream;
// I should handle the stream here, but at this moment, I don't know if it is POST or GET and what the possible post data is.
// so: I store these params in a "ServiceCallInfo" object and wait till I receive a "OnSendData"
}
private class ServiceCallInfo
{
private byte[] post = null;
private string path = null;
private Stream output = null;
private bool close = false;
private bool handled = false;
private bool relative = false;
public byte[] Post
{
set { post = value; }
get { return post; }
}
public string Path
{
set { path = value; }
get { return path; }
}
public Stream Output
{
set { output = value; }
get { return output; }
}
public bool Close
{
set { close = value; }
get { return close; }
}
public bool Handled
{
set { handled = value; }
get { return handled; }
}
public bool Relative
{
set { relative = value; }
get { return relative; }
}
}
}
}
If I fill the stream in "OnLoadExternalResourceBy*Path" as a test, it works:
Code: Select all
private void LoadExternalResource(string path, Stream stream, ref bool handled, bool relative)
{
// fill the stream based on some hard-coded variables (e.g. RequestType = post and post data is a byte array).
}
But if I do it like in the dummy code, it doesn't work.
Additional question:
What is the meaning/functionality of setting the "handled" boolean in "OnLoadExternalResourceBy*Path"?