公司的同事离职了,接下来的日子可能会忙碌,能完善DEMO的时间也会少了,因此,把做的简易DEMO整体先记录一下,等后续不断的完善。
参考两位大神的日志:WEB版微信协议部分功能分析、【完全开源】微信客户端.NET版
尤其是周见智大神的DEMO,因为好多和微信的服务端交互,都借鉴了大神的源码,帮助巨大,可以说我相当于做了一个翻版,只是用WPF开发的而已,外观上不同,但是实际交互上是差不多的。
微信分为两个部分,一个是登录,一个是主体,基于此,WPF也主要是这两个窗体来实现。
一、登录模块
1、登录部分分为二维码和获取用户头像两个页面(因为是给予WEB的,所以没有客户端的登录按钮,只能通过扫码来登录)
在程序启动以后,先通过请求获取到二维码,然后,在启动一个新的线程,不断的循环检索登录状态。


private void LoopLoginCheck() { object login_result = null; //循环判断手机扫描二维码结果 while (true) { login_result = ls.LoginCheck(); //已扫描 未登录 if (login_result is ImageSource) { HeadImageSource = login_result as ImageSource; //广播,通知到LoginUC页面,切换 Messenger.Default.Send<object>(null, "ShowLoginInfoUC"); } //已完成登录 if (login_result is string) { //访问登录跳转URL ls.GetSidUid(login_result as string); //广播,隐藏登录页面,打开主页面 Messenger.Default.Send<object>(null, "HideLoginUC"); thread.Abort(); break; } ////超时 if (login_result is int) { //QRCodeImageSource = ls.GetQRCode(); //返回二维码页面 Messenger.Default.Send<object>(null, "ShowQRCodeUC"); } } }
因为是MVVM,所以,需要用广播来进行操作页面的切换,即填充到登录窗体中间的控件是二维码,还是头像。
2、大家可以看到我上面的截图部分包含了一部分的背景,这个是用Snagit(推荐这个截图工具,很好用)截图时,自动截出的,因为窗体本身的大小就是那么大,多余出来的部分是透明的,用来做二维码滑动出现的效果部分。
当处于二维码状态时划过,则出现动画,头像状态下则没有动画,是设置了Image的Visibility属性来控制的,滑动效果可以看我的另一篇博客微信 二维码鼠标滑动 图像显隐效果。
3、当扫码成功,并且在手机端点击登录以后,则跳转到主页面,此处没有加异步等待处理,所以,用户量大的朋友,请耐心等待(后期会加上)。
登录成功以后,就会出现主窗体和系统托盘,主窗体包含最近联系人和通讯录,系统托盘网上很多解决方案,可以自行查找。
登录成功现在发现了一个问题,就是我有两个微信号,其中一登录以后是有数据的,另一个则没有数据。
跟踪代码,发现返回的Json是空的,也就是说没有返回值,试验了下周大神的代码,发现也是空的,不清楚什么情况,我同事的有的也是空的,这个一直没有深究,等把功能基本都完善以后再看看问题所在。
二、主窗体模块
1、主窗体的布局部分很简单,采用了Grid进行分隔,三列,上面的控件如图所示
大部分到没什么,可能大家比较疑惑的是我的聊天窗体为什么是ListBox,这个东西的话,我认为,自己有自己的开发习惯,很多控件都可以实现,panel就可以。
RadioButton的样式是用path画的,可以看我另一篇博客微信聊天和通讯录按钮样式
2、聊天列表里,未读的消息上会有带数字的小红点,这个是用Button写的,Item的整体组成是Image(头像)、Button(未读数)、TextBlock(昵称、时间和聊天内容)


<Style x:Key="ListBoxItemChatStyle" TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Border> <StackPanel x:Name="sp" Orientation="Horizontal" Height="{Binding Converter={StaticResource objectToHeight}}" Background="{Binding Converter={StaticResource objectToColor}}"> <Grid> <Image Source="{Binding Icon}" Width="40" Height="40" Margin="10"/> <Button Foreground="White" Visibility="{Binding UnReadCount,Converter={StaticResource countToVisibility}}" Content="{Binding UnReadCount}" HorizontalAlignment="Right" VerticalAlignment="Top"