2025-09-21 22:58:39
娘俩出去逛街,带回来一个新家庭成员——豹纹守宫。
粉嘟嘟的,相当可爱,非常老实。不吵不闹不臭不咬人,比仓鼠好伺候多了,难度跟养鱼差不多。
唯一的问题是,哪有豹纹?
某天晚上,臭宝用老婆大人的手机点了外卖,我都不知道她俩点的什么。外卖送来的时候,一个在洗澡,一个在屋里吹空调刷手机,我看也没看就给收了。
老婆大人洗完澡出来,接到外卖小哥的电话,他把两份外卖弄混了,问能不能换回来。老婆大人表示,没动就可以送回来。反正我们这份是没动。
过一会儿,外卖小哥回来,又是我开门,一顿点头哈腰,说:“不好意思,那边打开了,不过我看没吃,你们还可以吃。哥你看行不行?”
我说:“我看行不行有P用啊,又不是我买的!”
外卖小哥不知道是没听清还是没听懂,拿走我手里要换走的那份,东西放下就急匆匆跑了。
老婆大人出来一看里层袋子打开了,直接就申请退款。平台看到照片,配合早已超时的事实,二话没说就给退了。
第二天傍晚,娘俩又去逛吃,我自己在家。忽然有人敲门,一看是昨天的外卖小哥,还另带了一个光头花臂膀大腰圆的人。
光头佬上来就先声夺人:“你们昨天订外卖,怎么不先联系我们外卖员就直接退款了呢?”
我:“你谁啊?”
光头佬:“我跟他一个站点的。”
我:“哦,那没你事,让他说。”
光头佬:“这样你只能把昨天外卖还给我们,我们退给商家。”
我:“你闭嘴,让他说。”
——一听就是被罚了气不过,过来吓唬人找心理平衡的。大夏天的,哪个商家会给退卖出去一天多的东西?更何况是外卖平台都处理完了。
外卖小哥一看就没多少社会经验那种,话说的磕磕绊绊:“哥,那个,昨天那个外卖,你给找出来,我,我去给退给商家。”
我想都没想,直接说:“扔了。”
光头佬一下子来劲了:“扔了让我们怎么退,你得把钱退给我们。”
我:“你闭嘴,没你事,让他说。”
外卖小哥重复一遍:“大哥,你把钱——”
话音未落,光头佬发现了我放在门口的包装袋子:“你不说扔了吗,一看就是吃了,XXXXXX”
我真的不想的。孩子嘴馋,昨天要吃,老婆怕被吐口水都没让吃。
不仅一口没动,反而多摞了两泡猫屎。我白天没出门,所以没来得及扔。
既然你们这么想要,我就一边笑一边把包装袋递给了光头佬。
我:“你拿好了,仔细检查检查,我们一口没吃。”
光头佬脸都绿了:“你这太恶心了,你让我怎么退!”
我:“你自己非要要的。有问题找平台吧。”
关门。
光头佬在门外又骂了两句,说了几句:“你这个门我看挺好啊”之类肌无力的话。
打给老婆说了声,她给平台反应了一下。
几分钟后,平台给我来电话,说外卖员因纠纷上门是严重的违纪行为,已经暂停他资格了。
活该。
他们应该庆幸是我在家,换我老婆直接就报警了。刚好不久前片警大哥通过业主群加了小区里所有人的微信,喊他过来都不用打110。
老婆还顺手把没关好门的物业保安也给投诉了。
老婆回来之后,说:“咱真不怕他们上门找麻烦吗?”
我:“他要有那本事,还会去送外卖?”
某日,人行道上遇见一哥们,岁数看着跟我仿佛,双臂花里胡哨的,但是走路却不怎么利索,有点“拐小筐”。
我心想,都是浩南哥害的,这男子汉的勋章来的有点猛啊。
走近了偷瞄,画的不是什么青龙白虎山精海怪。左臂纹的几个大字是“瞬 冰河”。
看来是因为不纹生命力强大的第一主角,被反噬了。
臭宝开学之后,全家的作息时间重新调整。我起床时间从5:50提前到5:25。由早起变为更早起。
5:48下楼,陪臭宝去班车点等班车。班车6:00准时到。
最大的困扰是,网易云坏掉了——9月份之后出门,日推总是不更新。
直到第一个周末,恍然发现,网易云其实没问题,只是日推每天到了6:00才会更新。
看着臭宝的背影,戴上耳机,响起一天的背景音乐。
臭宝的班级成立了家委会,组织了家长群。我是在军训汇报表演的时候扫码加入的,老婆大人是在我回家后被我拽进群的。
家委会成立后第一件大事,是每人收100块钱班费。
一看这负责收钱家委就没有经验,她发起的群收款,对象是每个家庭第一个加群的家长(有经验的都找XXX妈妈收钱)。
我一下午没看手机,到下班的时候发现老婆大人打了8个电话催我交钱。
交完钱以后,想跟家委解释一下工作时间不能看手机,字没打完又给删了。我解释那么多干嘛呢。
退群,然后重新加入了。这样老婆大人的名字就排在了我前面。
两天之内,陆续有人学样退群重新加入。最后加入的昵称都是XXX爸爸。
臭宝学校的伙食可能太好了。
上周四中午,班里几个男生比赛吃包子。
班里剩下的所有人人乐此不疲地帮他们去跟打饭阿姨要加包子。
冠军吃了21个,亚军19个。
晚自习的时候,亚军吐了一地。
时代在变,中学男生的愚蠢不变。
赢了,你是头号饭桶;输了,你还不如饭桶。
手机APP令牌二次认证这玩意儿太讨厌了。
前两天Github的认证,死活过不去。我都想重置了,看看提示里的1-2个工作日人工审核,又打了退堂鼓。
好在终于想起来,我刚才用的是口令App3号,号称可以用来加github账号,但是我加失败了。应该用口令App1号来的。
1号是Github用的,2号是公司用的,3号是微软系用的。
妈的纯刁难老年人。
家里的Windows,再一次升级失败出蓝屏。
你说它考虑老硬件了吧,它升级出蓝屏。
你说它不为用户考虑吧,重启了几次之后还能退回来,然后右下角弹出一行小字:“我们已经为您跳过此次升级。”
我可能是正版软件的受害者。
我前面是不是说守宫好养活?
屁咧!在你养一个东西之前,你最好明确知道自己养的是什么。
爬虫类的东西,吃活食。
闺女养守宫,我替守宫养面包虫。
5块钱给了一大坨,至少300根,小守宫一天吃5根。
我tm这辈子买东西第一次嫌老板给多了。
很好养,喂点馒头就行。
不喂馒头,会饿死。喂了馒头,会蜕皮,因为虫口太密集,也有憋死的。
这东西一死一片,所以要及时把死掉发黑的捡出来扔掉。我会叠个纸盒,把活虫子一根一根捡进去,把塑料盒里剩下的死虫子、虫蜕和粑粑清理干净,再把纸盒里的虫子倒回来。每周两次。
我是不怕虫子,不等于喜欢摆弄虫子啊。
好像熬过这两三个月之后就不用再养面包虫了——守宫长大以后,吃蟋蟀。
不过有一说一,看面包虫吃馒头还挺治愈的。你会发现“蚕食”这个词发明得真好。
搁30年前,高低要嚼两根尝尝味道。
想想这么干以后,除了老婆责骂以外任何小女生的青睐鄙视或好奇都获得不了,还是算了。
老男人并没有变聪明,只是学会计算利益了。
那哥们右臂纹的是:“死牙马 龙魔”。
注:夫=大姨夫。
2025-09-17 16:08:03
前早上班,小祁在群里临时请假,说上班途中遭遇了事故。
两小时后她到了单位,备述事情经过。
事故本身平平无奇:
早起出门,夫妻俩先把儿子送到幼儿园后,他老公接下来把她送往地铁站。在途经一所初中旁边没有红绿灯路口的时候,忽然从右边路口窜出一辆右转摩托车,没控制好转弯半径,直直撞到了后门上。车门被撞了个坑,骑手也摔出去好远。
值得说的是后续。
因为早高峰离学校很近又是路口,所以交警第一时间就站到边上了。摩托车骑手是个女的,接近50岁。她从地上爬起来之后,不顾一只胳膊已经抬不起来,第一件事就是直接给警察滑跪:坦诚自己没驾照,求警察高抬贵手,要跟小祁两口子私了。
警察此时只在乎周边秩序,表示:“只要你们能赶紧谈妥赶紧走,我可以当没看见。”
于是女骑手找到小祁持续卖惨:家里三个男孩,老大初三,老二初一,老三小学二年级。有C票(有P用?),没有摩托车票。她老公开车送老三上小学。她自己骑摩托先送老大,再送老二,因为这个初中三个年级在不同校区。她早上起来给孩子做饭太早了以至于睡眠不足。她不能走程序,因为晚上还要接孩子,她不能被扣车。
小祁也没经历过这些,就问警察叔叔,公了是什么流程。
警察叔叔表示:“摩托车100%责任,公了就是她赔你修车钱。但你这边可能要走交强,赔她一千多块最低医疗费。也就是你们互相赔。我们扣她车,她之后交罚款赎车。”
小祁可能是觉得出险也不划算,也就同意了私了。拍照问四儿子修车需要多少,四儿子说:“1600。”
小祁两口子让对方录了保证不追讨医疗费的视频,录了好几遍。
对方微信上转不出1600块,打电话给她老公要钱,撕扯半天,期间能听出,老公竟也不知道她没有摩托车票。
转完账,小祁看着对方胳膊于心不忍,返了400回去,说:“你先去医院看看胳膊吧。”
对方眼含热泪收了钱,深鞠一躬,说:“谢谢,你是好人。但我还是要去上班。要迟到了。”
跨上摩托就走了。
2025-09-12 09:40:36
最终效果见这里。
我这个人既不喜欢旅游,也不喜欢摄影,没出过国也没在国内溜达过几个地方,但这并不妨碍我也有一颗上线足迹地图的心。无奈谷歌地图连不上,百度地图不想连,OSM(OpenStreetMap)既连不上也连不明白,就搁置了。
直到上周,@Dayu上线了他的地图插件,试用之后发现表现形式与期待值有差距,想在帖子下面留言发建议的时候,发现了明明同学的另一份方案。虽然主要是js实现的,只需要知道leaflet这个开源库的名字,我就知道以Wordpress的海量扩展,这回成了!
找到了一个插件和插件的插件,配置之后,算是达到了心目中的效果。
插件使用比较复杂,这里记录一下,给自己个备忘,能帮到人更好。
插件地址:Leaflet Map。
逐一说明一下后台的配置项:
Default Latitude:
地图默认纬度
Default Longitude:
地图默认经度
Default Zoom:
地图默认缩放比
Default Height:
默认高度
Default Width:
默认宽度
上面五个值可以以短代码参数的形式加到leaflet-map中,如果不加则使用后台的默认参。
Fit Bounds:
是否令地图随标记点的范围进行缩放。如果为true,那么地图会自动计算当前所有Marker的中心位置,以及包括所有Marker点的合适的缩放比。可以用默认值,也可以在map中单独设置。
Show Zoom Controls:
是否显示缩放按钮
Scroll Wheel Zoom:
是否允许滚轮缩放
这项设置之后,在地图上并不是直接用滚轮缩放,而是需要用Ctrl,感觉不便所以我自己没加。
Double Click Zoom:
是否允许双击放大
注意如果不显示缩放按钮的话,放大之后就回不来了。
Default Min/Max Zoom:
最小和最大放大倍数。最终的放大倍数不仅跟这个后台设定项有关,也跟使用的地图瓦片API有关。
Default Tiling Service:
有两个选项,“I will provide my own map tile URL”和MapQuest。MapQuest我考察了一番,感觉太难看,没继续尝试。所以重点说第一个选项,自定义tile URL。
先解释一下什么是tile URL。本插件所依赖的地图服务,叫做Map Tile Server(地图瓦片服务)。它分成Raster、Vector和Static三种形式。本插件使用的是Raster形式,而Dayu和明明同学用的都是Vector形式。Vector的参数更加丰富,Raster配置起来更简便。
※※※Map Tile URL※※※:
重中之重!!因为默认的OSM服务访问不了,所以这里必须填一个自定义的。
明明同学找的cartocdn就挺好用的。他使用的light_nolabels是不带标签的版本,换成light_all就是带标签的版本。至于他为什么用不带标签的,自己悟。
https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png
http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png
这里的{z}{x}{y}都不要动,第一个{s}是指地址里的subdomain,也就是接下来的配置项【Map Tile URL Subdomains】。
有的API是需要API Key的。这样的API都有说明文档,把Key按照人家给的例子粘贴进来即可。
cartocdn对我来说有点太素了,于是周末花了一天时间寻找能用的瓦片服务,结果惨不忍睹,汇报一下成果:
maptiler.com:要注册、被墙。
opentopomap.org:免注册、丑。
stadiamaps.com:要注册、比较流畅、免费用户限流严重
tomtom.com:要注册、慢、地图不详细
here.com:要注册、中文地名乱七八糟
geoapify.com:要注册、速度尚可、账号登录验证需要梯子,服务本身不需要。
至于为啥不找国内的地图服务,是我不想吗?本插件所支持的是Raster服务,也叫zxy服务,客户端GET的结果必须是一张PNG/JPG/WEBP图片。国产的高德和天地图我也试了,根本不是一样的格式。甚至有种说法,说国内不允许提供这种服务。
然后呢,这服务也可以自己搭建,数据和教程也都有,但总觉得这种行为像为了吃顿酱肘子先花一年时间晒酱油,没必要。
兜兜转转一圈,还是要回到cartocdn。什么功不唐捐,屁咧!
Map Tile URL Subdomains:
具体填什么要看API的文档说明,像openstreetmap和cartocdn都是abcde或a,b,c,d,e。有的API前面没有前缀那就不填。
Detect Retina:
是否检测高清设备。如果上面的瓦片服务中支持@2x,那么选中这项以后,如果leaflet发现使用者用的是高清屏幕,就会自动使用高清地图。窃以为意义不大。
Tile Size:
一般情况下服务本身已经设好了,留空即可。
Tile Id:
Access Token:
用Mapbox的服务才有用。但是我的Mapbox没配明白,只有一个默认的卫星地图能用,这两项也没用上。
Zoom Offset:
好像是在zoom的时候自动加减一下这个值,没理解意义。
No Wrap (tiles):
地图是否与经线对齐。(这有啥用?)
JavaScript URL、CSS URL:
css和js的位置,默认即可。
Default Attribution:
地图做成后,右下角的一串版权信息。尊重服务商要求即可。
再往后没用上。
插件装好后,其实已经可以编辑地图了。但因为还有个插件的插件,所以怎么用放后面再说。
插件地址:Extensions for Leaflet Map。
跟主插件正相反,这个插件的后台,大多数时间在说怎么用。
Marker Clustering–When you mouse over a cluster it shows the bounds of its markers.
聚合显示时,默认会将聚合的标记点连接起来形成一个多边形。我嫌不好看,勾掉了。
When you click a cluster we zoom to its bounds.
点击聚合点时,直接缩放到所有聚合点的范围。
语法和关键字很多,但能用上的不多。通常只需要地图、标记点、地形json文件。
leaflet-map:
主插件的主函数,用于插入一张leaflet-map。参数就是配置页面的那些,没什么特别的。
leaflet-marker:
标记一个地点。参数比较多,挑有用的说。
– lat,lng / address:用于定位标记的位置。lat是纬度,lng是经度。经纬度可以从OpenStreetMap.org上查。国产地图查到的经纬度与OSM查到的有一些偏差,注意要保持一致。而address的数据库偏差非常大,不建议。
– iconUrl:标记用图标。可以是网址,也可以是相对路径,甚至base64代码。如果不设,使用默认的蓝色pin图标。
– title:鼠标移动到标记点上时显示的提示信息。这个与点击标记后显示的内容是两码事。
– iconanchor:图标的锚点偏移。这个参数有点意思,它表示的是你图标的“尖”所在的位置。以默认图标为例,规格是19*25,“尖”在最下方,所以iconanchor就应该是宽的一半和全部的高,也就是10,25。这个参默认项是0,0。每个标记都要自己手动加,相当烦。不过也能够理解,一旦有人用的是左箭头呢?
– opacity:图标的透明度。
– 【leaflet-marker】【/leaflet-marker】之间,放置弹出的html内容。放啥都行,也可以定义css。
另外还有一些参数,我都没用上官网说明文档里都有。
leaflet-geojson:
地理信息的json文件。中国的地理信息文件可以在阿里云下载,或者直接引用。建议下载后到mapshaper进行优化后上传,在本地使用。这里非常感谢明明桑,一个优化工具解决了困扰我许久的问题。
– src:地理信息源文件的路径,可以是相对路径或网址。
– color:leaflet提供的属性,边框颜色。
– weight;leaflet提供的属性,边框宽度。
– opacity:leaflet提供的属性,边框透明度。默认的3px蓝色实在是有点虎。缺点是每个marker都需要单独设置。
– fill:leaflet提供的属性,布尔型,是否填充。默认true
– fillColor:leaflet提供的属性,填充颜色,不设则默认使用color
– fillOpacity:leaflet提供的属性,填充颜色的透明度,默认0.2
想一个省一个省点亮的,就下载省级json,想像我这样一个市一个市点亮的,就下载市级json,一次勾一个边即可。话说,我一直认为用省划分习俗非常不科学,甚至用市来划分都不科学。毕竟有粤南粤北、胶东鲁西南,还有江苏十三太保这样的众所周知的文化差异。我甚至觉得应该精确到县。毕竟我们旁边就有一个散装的地级市,我认识一堆人,他们分别来自鲅鱼圈、熊岳、盖州、老边、大石桥,就没有一个称自己是营口人的。但是真正实装以后才发现,县级太困难了,我甚至都没在普兰店歇过脚,自己家都没搞定。
markerclustergroup:聚合分组方法,这是“扩展的扩展”的功能,也是安装它的主要目地。cluster是指将临近的点进行聚合,group是通过关键字对追加的点进行分组。只聚合可以用cluster,只分组可以用leaflet-optiongroup。
– feat:适配项目。可以是【leaflet-marker】中的title或者iconUrl中的一个。参数以部分匹配的方式,对title或者iconUrl形成过滤,然后在右上角形成组别。
– strings:分组过滤用的字符串,用半角逗号间隔。
– groups:分组后显示的字符串。
– position :分组显示位置
– collapsed :分组是否折叠
【leaflet-map fitbounds】//用fitbounds,就不用关心点的位置和缩放了 【fullscreen】//增加一个全屏按钮 【leaflet-marker lat=38.87430121 lng=121.55204380 iconUrl="/path_to/marker-blue.png" iconanchor="15,40" 】<b>辽师附中</b><i>2012 /04 /<a href="/2012/04/ancient-school-motto.html" target="_blank" rel="noopener">沙河口黑石礁尖山街</a> /街拍 </i><img src="/path_to/imag0114.jpg" alt="imag0114" />【/leaflet-marker】 【leaflet-marker lat=38.88611421 lng=121.63731716 iconUrl="/path_to/marker-blue.png" iconanchor="15,40" opacity=0.5】<b>西岗中学</b><i>2003 /05 /<a href="/2023/06/post-truth-and-something-before-my-graduation.html" target="_blank" rel="noopener">西岗八一三环街</a> /其他 </i><img src="/path_to/vlcsnap-2023-05-21-17h15m27s675.jpg" alt="vlcsnap-2023-05-21-17h15m27s675" />【/leaflet-marker】 【leaflet-marker lat=38.88890 lng=121.70665 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>棒棰岛</b><i>1993 /08 /中山老虎滩迎宾路 /海滩 </i>【/leaflet-marker】 【leaflet-marker lat=38.93471 lng=121.19765 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>北海王家村</b><i>2018 /08 /旅顺北海王家村 /海滩 </i>【/leaflet-marker】 【leaflet-marker lat=38.98562089 lng=121.65895298 iconUrl="/path_to/marker-yellow.png" iconanchor="15,40" 】<b>蟹子湾</b><i>2015 /04 /<a href="/2015/04/chemical-factories-stories.html" target="_blank" rel="noopener">甘井子甘井子海茂路</a> /海滩 </i><img src="/path_to/BF59AEE251904BC4.jpg" alt="BF59AEE251904BC4" />【/leaflet-marker】 【markerclustergroup feat="iconUrl" strings="blue, yellow" groups="学校, 海滩" collapsed=true】 【leaflet-geojson src="/path_to/dalian.json" color="#FF8888" weight=2 fillOpacity=0.3】//加入大连地图 【zoomhomemap】//调整缩放比[fullscreen ] [markerclustergroup feat=iconUrl strings=blue, yellow groups=学校, 浴场 collapsed=true ] [zoomhomemap ]
就到这。总之有现成儿的我才不会亲自动手呢。
2025-08-29 20:33:05
某夜。看漫画看得犯困,又没到直接睡过去的程度,把电子书合上放在胸口,酝酿情绪。毛孩子2号猛地跳上我胸口跟我互动。撸了几下之后,猫和我都就都睡着了。
第二天早起发现,被9斤的小猫踩了一脚之后,酱婶了:
这玩意儿叫做墨案Air6。
我这人遇到好东西一般不会夸,但遇到差东西就一定会骂。既然坏了,那就得说道说道了。墨案Air6只有一个优点,就是轻便。
剩下全是缺点。它的破系统我早就想吐槽了。买的时候是本来冲着开放系统去的,到手之后发现除了自带市场里的小猫两三只,自己找的软件80%都是装不上或者闪退,10%会在3分钟之内卡死或自动退出。电量也不太能打,连续用不到5个小时就歇菜了。
倒不会把它加到黑名单里,因为估计这牌子也坚持不了几年。
在最后尝试抢救的时候,意外发现墨案号称是杂粮生态链上的。
哟吼吼,把屎盆子扣杂粮头上我可是一点儿心理负担都没有。杂粮在我心中本就离“永不录用”一步之遥。
真正在黑名单上的是创维。我姑娘早上9点出门的时候电视没关,下午4点回来,发现白屏了,断电重启都不好使的那种白屏。
自己尝试刷机无效,还是找了修家电的师傅上门。
拆机用表量了几个脚,说是板烧了,屏没事。换板550,问还修不修。
这电视修的,根本也不去给你查是板子的哪个零件坏了,也根本没有动烙铁的意思。
我自己上还真不行。首先我没法判断是板坏了,其次这板的型号我在某宝上还真没搜到。
这个价格拿捏得刚刚好。平常确实是几个月都不开,可明年还得看球,2028年还得看球,2030年还得看球……
拆!
十年前的电视,电路板分成泾渭分明的两部分,一半就是个机顶盒,另一半负责控制屏幕,两板间有几组排线。
一周后新板到货,涛声依旧了。师傅走前特意叮嘱:“这板子已经不太好找了,我跟你说啊,用创维的电视,千万别升级,就当成个显示屏用就行。反正我看你也是配了机顶盒。”
从善如流,干脆网络都不配。
公司又换名字了。这次工资卡也会同时换成浦发。
上门办工资卡的同时推销的信用卡,“开卡豪礼”可以是个小风扇或者某视频网站的VIP季卡。部门还真有人要了那个VIP季卡。
回家充会员的时候,发现这卡也太狗了:每个月可以激活VIP7天,到下个月可以再激活VIP7天,下下个月还可以激活7天,最后失效。
就问你跨了3个月是不是一季吧!
某日早上,工作机提示密码即将过期。改完密码后登邮箱,停在在二次验证的弹窗画面上,死活刷不出来。
找IT的小伙来解决。我们彼此能叫上名字,他知道我搞不定的问题一般都不太常见,一进门便神色紧张。
我说:“给你看个稀罕东西,Outlook把IE给弄出来了。Win11下的IE你见过吗?”
哥们当时就懵了。试着给我清用户清缓存,又登录网页版反复修改邮箱配置。又用他的管理员账号配置他自己的邮箱,也卡在同样的地方。
一个多小时毫无效果。
他忽然想起来:“你给我打电话之前,重启过没有?”
一阵振聋发聩的沉默。
臭宝学校的军训开始了。感觉学校根本就怕出事,千方百计地在拖延时间——每天训练,上午8:00开始,午休11:30到14:00,下午16:00回教室写当天的军训总结。
教官是从某军校找来的大二学生。
原本的计划是7天,第一天之后缩短到6天,第二天又通知要抽出半天看电影。刚才又通知,最后一天的汇报表演原定是下午3小时,改成早上2小时。
总之就是一副赶进度跳流程的样子。
这种糊弄让我觉得这学校目前看还挺务实的,没苦硬吃样子货就应该这么糊弄。
注:夫=大姨夫。
2025-08-20 22:31:00
客户提了个需求:因为他们的显示器(32吋)大,所以经常把缩放比设成125%或者150%,希望我们的APP在这两个缩放比下能够正常显示。
但是我们干活用的只是普通的24吋,设成150%之后高度就出溢出屏幕了,这就需要加滚动条。而工作这个东西,到了二鬼子领导那里就会加码,变成100%-225%都得能正常运行,并且因为增加的高度与原来的高度相比没多太多,所以要大滑块,不要分的细碎的小滑块。
这个功能本身不难。通常的做法是取屏幕放大后的窗口新高度,然后减去桌面有效视窗高度,得到的差值除以一个系数,然后用SetScrollRange的第三个数给传进去。然后重写OnVScroll方法,从系数反推滑块位置。
但是,这样得到的是小滑块,而且最后一屏的空白部分也不准确,往往会出现大片空白。
研究了好几天,终于找到了还算不错的方案。在此分享一下。
注意,我只写了垂直滚动条,因为我们的窗体就是瘦长型,即使增加到225%也没超出屏幕宽。给公家干活的一个要务就是不干多余的事,所以要添加水平滚动条的自己酌情修改,我这里就不提供了。
开始。
如需要增加则对垂直滚动条进行初始化。初始化时,不使用简化版的SetScrollRange(),而改用SetScrollInfo()。利用结构体SCROLLINFO的nPage和nMax配合实现大滑块。这里的逻辑是:nPage与nMax的比值也就是滑块占总高度的比值,比值越接近一,滑块越大。nPage和nMax都是相对值,只要二者单位统一即可。方便起见直接使用真实值。
一个很坑的点是nMax不能用窗口Rect的高,而要取最下边控件的下沿,原因未知。
下面是代码:
BOOL CMFCAppDemoDlg::OnInitDialog() { CDialogEx::OnInitDialog(); //取窗口位置 CRect rcThis; GetWindowRect(&rcThis); //取最下面控件的位置,如果有动态创建的控件,可以遍历取得。 CRect rcLastButton; GetDlgItem(IDCANCEL)->GetWindowRect(rcLastButton); //取放大倍数,96.0是100%时候的DPI float fScale = static_cast<float>(GetDpiForWindow(m_hWnd)) / 96.0; //取桌面工作区大小 CRect rcScreen; ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0); //对话框的工作区域理想高度:比最后一个控件多一丢丢。 int nHeightImage = rcLastButton.bottom + rcLastButton.Height() * fScale; //如果想象高度比工作区域高,那么将窗口高度设为与工作区等高。 if (nHeightImage > rcScreen.Height()) { m_blHasVScrollBar = true; //成员变量,用于标记是否有滚动条 rcThis.bottom = rcThis.top + rcScreen.Height(); this->MoveWindow(&rcThis, TRUE); //修改Dialog自身高度 SCROLLINFO si{}; si.cbSize = sizeof SCROLLINFO; si.fMask = SIF_RANGE | SIF_PAGE | SIF_PAGE; si.nPage = rcScreen.Height(); //Windows桌面可利用高度作为Page高 si.nMax = nHeightImage; //窗口高度最大值。 SetScrollInfo(SB_VERT, &si, TRUE); //激活滚动条 } //否则没用滚动条 else { SetScrollRange(SB_VERT, 0, 0, FALSE); } return TRUE; }
没有难点。只要每个消息处理时,nPage与nMax的比例关系一致即可。
BEGIN_MESSAGE_MAP(CMFCAppDemoDlg, CDialogEx) ON_WM_VSCROLL() END_MESSAGE_MAP() void CMFCAppDemoDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar); //取之前的滚动条信息 SCROLLINFO si{}; GetScrollInfo(SB_VERT, &si, SIF_ALL); //滚动条上一次的位置 int nCurPos = si.nPos; const int FACTOR(100); switch (nSBCode) { case SB_LINEUP: //Scroll one line up nCurPos -= (si.nPage / 50); //点击一次箭头,或者按一次↑,移动页面的1/50,注意方向 break; case SB_LINEDOWN: //Scroll one line down nCurPos += (si.nPage / 50); //注意方向 break; case SB_PAGEUP: //Scroll one page up nCurPos -= (si.nPage / 50* 20); //PgUp键的处理。所有的响应要统一单位标准即可。注意方向 break; case SB_PAGEDOWN: //Scroll one page down nCurPos += (si.nPage / 50* 20); //注意方向 break; case SB_THUMBPOSITION: //Scroll to the absolute position. The current position is provided in nPos nCurPos = nPos; //从缩略图直接确认位置 break; case SB_THUMBTRACK: //Drag scroll box to specified position. The current position is provided in nPos nCurPos = nPos; //从滚动条直接确认位置 break; case SB_ENDSCROLL: break; default: break; } //确认没有超出最小值和最大值范围。最小值一般是0,最大值是nMax - nPage。 nCurPos = max(si.nMin, min(nCurPos, si.nMax - static_cast<int>(si.nPage))); //当位置移动时,滚动窗口内容 if (nCurPos != si.nPos) { int nDelta = si.nPos - nCurPos; //注意方向,原始值减目标值 si.nPos = nCurPos; si.fMask = SIF_POS; SetScrollInfo(SB_VERT, &si, TRUE); //设滚动条 ScrollWindow(0, nDelta); //滚动窗口 UpdateWindow(); } }
同样没有难点,只是鼠标滚动一下会转化成多次向上或向下的消息。
BEGIN_MESSAGE_MAP(CMFCAppDemoDlg, CDialogEx) ON_WM_MOUSEWHEEL() END_MESSAGE_MAP() BOOL CMFCAppDemoDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { //确认滚动条有效 if (!m_blHasVScrollBar) { return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); } CONST INT WHEEL_SCROLL_LINES(3); UINT8 ucDirection(SB_LINEUP); //根据zDelta方向确定消息重量 if (zDelta < 0) { ucDirection = SB_LINEDOWN; } //把鼠标滚动值换算成N个箭头消息并发送。次数是没有方向的。 UINT unLines = (abs(zDelta) * WHEEL_SCROLL_LINES) / WHEEL_DELTA; while (unLines--) { SendMessage(WM_VSCROLL, MAKEWPARAM(ucDirection, 0), 0); } return TRUE; }
总之,最难的其实还是开头。nPage与nMax虽然设什么数都可以,但只有用真实值才是最符合拖动规律的。
2025-08-06 20:58:31
去重庆之前,我把属于自己的BUG都改完了,而项目的BUG还剩3个。我满心以为他们能在4天里把剩余的BUG改好,这样的就不用回伊尔廷一下飞机就加班了。
结果,这帮人改好1个,又新测出了3个,我还在重庆观音桥喝冷饮的时候就收到了PM的电话,确认6月29日的加班。
其中一个新增的BUG确实诡异,现象是播放视频的过程中突然崩掉。这几个人实在太勤快了,4天时间写了2000多行的代码,因为没有头绪,所以只能一版一版回退,然后差分定位问题。光是找原因就花了一周。
原来是leader小雨嫌视频的加载过程太慢,想出了给每帧各自起一个线程加载的大聪明办法。通常来说这种用资源换时间的做法倒也无可厚非,只不过我们自行开发的那个写日志的DLL自从2008年以来就没更新过,是进组时间仅次于我的第二老的家伙。当初写DLL的哥们根本没想到会被这么用,接入线程的最大数随手写了个32。
源代码倒还在,不过升级的成本有点高。直接把线程里的写日志注掉了事。
这么个破玩意儿改了6天,心情大坏。
另外一个BUG是视频保存的处理太慢。看下现象,打开任务管理器瞅一眼就知道原因了。
跟小木头说:“内存满了。想办法加快写的速度。每帧单独落盘,或者弄个磁盘映射试试。”
小木头的回复出乎我的意料:“大致哥,什么是磁盘,什么是内存?大的那个是磁盘,小的那个是内存,对吗?”
“在你的开发机上可以这么理解。”
“那手机上呢?”
“手机厂商现在比较缺德,都给都叫成内存了,实际上以前叫内存和闪存。叫运存那部分没问题,剩下那块爱咋叫咋叫吧。”
“那换你怎么叫?”
“Memory和Storage。”
疫情之前的那一年,公司邮件推荐过一家培训机构,考职业资格证有优惠。对我们来说有意义的是健康管理师、人力资源师、导游之类门槛低又能抵税的证。好事的女同事们有不少人报名参与。考过的话补贴加上抵税省的钱,减去报名费,还略有盈余。只是这家培训机构跟公司的合作只有一年,后续她们每年都是在群里报新的培训,跟公司没什么关系了。
忽然有一天,政策变了,国家的补贴是没了还是变少了什么的。培训机构也随之变了脸,只给发教材和网课网址,甚至有几门课都没给考试报名。同事找过去,先是推脱,继而跑路了。
有人一怒之下打了12345,也有人报了警。报警之后统计了一下(我们部门的)受害者名单,然后也没了下文。
又过去一年。上个月忽然有110给牵头的小琳打电话,让她去公安局了解情况。这路子太像诈骗了,她也没搭理。最后警察叔叔打到了公司前台,算是正式发出了协助调查的邀请。
小琳于是只好请了半天假去了公安局。原来,是培训学校在政府部门的内线出了问题——给不具备考试资格的学员非法安排考试资格(比如高级心理咨询师本来需要前置条件,但是该培训学校在内线的安排下交钱就能考),连带着搜集一下培训学校违法的证据。
小琳顺便问一下,钱能不能给退。
答曰等着吧。并且友情提示,让回来后别的同事也注意随时接110电话,配合调查。
几个老娘们就以这个为由,申请带手机进开发间。PM睁一眼闭一眼同意了。
这一个月过去了,并没有任何一个人接到110来电。
也许是因为只有小琳自己报了高级心理咨询师吧。
走廊对面的开发间被另外的部门占据了。又是一个严格要求控制手机的项目,他们比我们更惨,手机放在类似澡堂子里那种透明的抽屉里,谁手机没锁一目了然。而我们好歹还是不透明的铁皮柜子。
这个部门有很多年轻的妹子。不知道公司现在的着装规定是不是过期了,这帮妹子经常穿吊带上班。也有穿凉拖的。也有把头发焗成粉色蓝色绿色的。甚至还有纹身和打鼻环的。
难到我们公司收购了某个商K?
这帮妹子穿着打扮方面违反规定跟我半毛钱关系也没有,只是看着不忿。但有一样违规是实实在在妨碍到我了。
这些人不按规定在食堂吃饭,非要在开发楼层吃。
你以为我要抱怨饭味儿?错!
我忍不了的是,这帮人吃完饭要在洗手间聚众刷碗!三个面池全占,边刷边聊,特别的慢!这导致了我中午上完厕所没法洗手!我总不能站在她们身后一直盯着屁股看吧。
尿个尿而已,为此走到别的楼层去洗手又特别不甘心。
没办法,只好拉长上午带薪拉屎的时间,尽量排空了。
7月25、26日(周五、周六)时代少年团在伊尔廷开两场演唱会。
演唱会的票那是一定没抢到的。问了个比较靠谱的票贩子,给的报价是,480的山顶票4000;680的票最抢手,6000;1680的性价比最高,只要12000。但是,不保证有,票贩子也得乖乖去主办方那里排号。
那就只好去你妈的了。
7月22日臭宝高中学校报到。去报到前,让臭宝把考完试做的美甲给卸了。她们娘俩做好了约定,演唱会臭宝要去场外,去场外前要把美甲再做回来。
报到当天(周二),衔接班更改了上课时间,12:30到晚上20:30,这样她就没有时间去做美甲。
接下来的周三和周四又都是有其他学校报到,上课时间同样变成12:30到20:30。
这样一来,臭宝就没有时间做美甲了。是的,我此时才知道做个美甲要2~4个小时甚至更久。
为了不耽误课的同时还能做上美甲,娘俩在某音、某团和小某书上找到半夜,找到一家早上8:30就开门营业并且有优惠价的美甲店。这样臭宝周四上午去做美甲,后面的课完全不耽误。
只是这家店所在的地方有点偏,臭宝之前从没去过,让她自己去我们两口子都不放心。
于是决定,我请假半天,带臭宝去做美甲。
一个皆大欢喜但只有我受伤的世界达成了。
注:夫=大姨夫。