zoukankan      html  css  js  c++  java
  • [WPF源代码]QQ空间相册下载工具


         放一个WPF源代码,源代码地址

        http://download.csdn.net/detail/witch_soya/6195987


         代码没多少技术含量,就是用WPF做的一个QQ空间相册下载工具,效果见上一篇文章。

         http://blog.csdn.net/witch_soya/article/details/8494712


         注意~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

         因为这个获取相册的方式是通过网上找到的QQ空间接口来的,所以不保证一直有效。最稳妥的方式是对浏览器访问QQ相册进行抓包分析,这个就不做详细分析了。



        



    说一下软件的流程 。


        QQIdea这个工程是下载图片的也就是左边这个类似于QQ登陆框的这个,3DGalaxy这个工程是用3D效果显示图片的。也就是右边这个相册预览的程序,两个exe程序之间通过进程通讯的方式实现互动。整个软件没有进行比较详细的规划,所以代码风格有些乱,还有些逻辑上面存在一些bug,现在没有时间修改,放出代码给有需要的同学一个参考。



         QQIdea这个工程的原理是这样

       1.从编辑框获取要下载相册的QQ号码。

      2.获取相册Route

         http://route.store.qq.com/GetRoute?UIN=QQ号

    得到返回的内容类似这样


    XML Source Code
    <?xml version="1.0" encoding="gb2312"?>
    <data>
    <uin>634963471</uin>
    <r>photo.qq.com</r>
    <u>hzup.photo.qq.com</u>
    <nu>hz.photo.qq.com</nu>
    <p>hznewp.photo.qq.com</p>
    <s>hzstatic.photo.qq.com</s>
    <read>1</read>
    <write>1</write>
    <idcno>2</idcno>
    </data>

      

    返回可以查看的相册的信息(包括ID等)
    这里的hzalist是根据上面的route而替换的
    http://hzalist.photo.qq.com/fcgi-bin/fcg_list_album?uin=634963471
    得到的信息如下  


    <?xml version="1.0" encoding="gbk"?>
    <data>
    <album>
    <anonymity>0</anonymity>
    <bitmap>11000000</bitmap>
    <classid>0</classid>
    <comment>1</comment>
    <createtime>1326087421</createtime>
    <desc/>
    <handset>2</handset>
    <id>V11db8OS2zV1ME</id>
    <lastuploadtime>1357654102</lastuploadtime>
    <modifytime>1357654102</modifytime>
    <name>贴图相册</name>
    <order>0</order>
    <pre>http://a223.photo.store.qq.com/psb?/V11db8OS2zV1ME/y7FgmoTf4iFSPSRtVI2XpzMfo8SbXdMFrsWFKZ7mfeM!/a/YcxY94RNAAAAYta274RQAAAA</pre>
    <priv>1</priv>
    <pypriv>4</pypriv>
    <total>52</total>
    <viewtype>0</viewtype>
    </album>
    <left>
    <album>

    注意这里得到了相册的名称是 贴图相册  相册的<pre>标签的内容就是预览图地址了。
    得到相册的id=V11db8OS2zV1ME

    接着访问
    http://hzplist.photo.qq.com/fcgi-bin/fcg_list_photo?uin=634963471&albumid=V11db8OS2zV1ME&outstyle=1&t=0.1740948824551711

    得到相册的所有图片的地址,名称等等信息开始下载。

    下载完毕后通过进程通信的方式通知3DGALXAY工程加载图片


    进程通信的方式如下。首先定义一个信使类

    public class MessageHelper
            {
                public const int WM_COPYDATA = 0x004A;
    
                [DllImport("User32.dll", EntryPoint = "SendMessage")]
                private static extern int SendMessage
                (
                IntPtr hWnd,                   //目标窗体句柄
                int Msg,                       //WM_COPYDATA
                int wParam,                                             //自定义数值
                ref  CopyDataStruct lParam             //结构体
                );
    
                [DllImport("User32.dll", EntryPoint = "FindWindow")]
                public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
                /// <summary>
                /// SendMessage To Window
                /// </summary>
                /// <param name="windowName">window的title,建议加上GUID,不会重复</param>
                /// <param name="strMsg">要发送的字符串</param>
                public static void SendMessage(string windowName, string strMsg)
                {
    
                    if (strMsg == null) return;
    
                    IntPtr hwnd = FindWindow(null, windowName);
    
                    if (hwnd != IntPtr.Zero)
                    {
                        CopyDataStruct cds;
    
                        cds.dwData = IntPtr.Zero;
                        cds.lpData = strMsg;
    
                        //注意:长度为字节数
                        cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;
                        // 消息来源窗体
                        int fromWindowHandler = 0;
                        SendMessage(hwnd, WM_COPYDATA, fromWindowHandler, ref  cds);
    
                    }
    
                }
    
                /// <summary>
                /// SendMessage To Window
                /// </summary>
                /// <param name="windowName">window的title,建议加上GUID,不会重复</param>
                /// <param name="strMsg">要发送的字符串</param>
                public static void SendMessageByProcess(string processName, string strMsg)
                {
    
                    if (strMsg == null) return;
    
                    var process = Process.GetProcessesByName(processName);
                    if (process.FirstOrDefault() == null) return;
                    var hwnd = process.FirstOrDefault().MainWindowHandle;
                    if (hwnd == IntPtr.Zero) return;
    
                    if (hwnd != IntPtr.Zero)
                    {
                        CopyDataStruct cds;
    
                        cds.dwData = IntPtr.Zero;
                        cds.lpData = strMsg;
    
                        //注意:长度为字节数
                        cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;
                        // 消息来源窗体
                        int fromWindowHandler = 0;
                        SendMessage(hwnd, WM_COPYDATA, fromWindowHandler, ref  cds);
    
                    }
    
                }
    
    
                [StructLayout(LayoutKind.Sequential)]
                public struct CopyDataStruct
                {
                    public IntPtr dwData;
                    public int cbData;//字符串长度
    
                    [MarshalAs(UnmanagedType.LPStr)]
                    public string lpData;//字符串
                }
            }


    在下载完毕后通过调用信使类的发送函数来通知3DGalaxy.exe展示制定地址的图片

    //下载完毕就通过进程通信方式通知Galaxy.exe加载
                    MessageHelper.SendMessage("QZone-Album Ver1.0 By Witch_Soya2013",strLocalPath);



    在3DGalaxy.exe中接收进程之间的消息方式

    首先在构造函数中添加进程通信功能

     //添加进程通信功能
       Loaded += new RoutedEventHandler(MainWindow_Loaded);
    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
               // throw new NotImplementedException();
                (PresentationSource.FromVisual(this) as HwndSource).AddHook(new HwndSourceHook(this.WndProc));
            }


    接着就开始处理进程之间的消息

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                //throw new NotImplementedException();
                //收到进程通信之间的消息
                if (msg == MessageHelper.WM_COPYDATA)
                {
                    CopyDataStruct cds = (CopyDataStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
                    //MessageBox.Show(cds.lpData);               
                    string strUrl = cds.lpData;
    //这里就获取到了需要展示的本地图片地址,添加到展示框中去
                    imageSwitchView1.AddImage(strUrl);                
                }
                return hwnd;
            }
    
            public class MessageHelper
            {
                public const int WM_COPYDATA = 0x004A;
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct CopyDataStruct
            {
                public IntPtr dwData;
                public int cbData;//字符串长度
                [MarshalAs(UnmanagedType.LPStr)]
                public string lpData;//字符串
            }



    整个的流程就是这样。至于WPF3D效果,界面的白云树叶飘动效果,就是一些基础的StoryBoard特效,可以去看深入浅出WPF。


    /********************************Witch_Soya*********************/

    /*******************************2013年9月2日11:02:11*********************/










  • 相关阅读:
    Re:从零开始的领域驱动设计
    领域驱动设计和Spring
    深入JVM分析spring-boot应用hibernate-validator
    深入Spring Boot:那些注入不了的Spring占位符(${}表达式)
    Android 使用OKhttp获取response时遇到的坑
    Android EditText组件drawableLeft属性设置的图片和hint设置的文字之间的距离
    Android 自定义spinner下拉框实现的实现
    Android You need to use a Theme.AppCompat theme (or descendant) with this activity.
    Android中取消GridView & ListView默认的点击背景色
    Android 显示 PDF 文件
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3297519.html
Copyright © 2011-2022 走看看