Introducing WMC mini-mods

Discussion of getting WMC to work on Windows 11 (unsupported)
User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#81

Post by Kevin Chalet » Sun Mar 17, 2024 1:15 am

Engineer wrote: Sat Mar 16, 2024 5:26 pm The individual program information that is briefly display when switching live TV channels is too short - it often cuts off/fades away program information. Additionally, the network name under the channel number is also too short for some networks. It looks to me that fade out length does not even make it to halfway across the available screen area. Is it possible to individually lengthen these two areas?

Thank you,
Will
Changing the "skin files" is out of scope for this project - which exclusively focuses on patching the WMC .NET assemblies - but it's fairly easy to customize that yourself.
For that, you can use the excellent/fantastic/magical/impressive/incredible Media Center Themer tool: https://www.thegreenbutton.tv/wiki/inde ... ter_Themer :mrgreen:

The file you're looking for is called INFOBARHINTING.MCML.

Here's an example of an edited version that uses larger fonts and a much larger MediaInfoPanel size (1000 instead of 359):

Code: Select all

<Mcml xmlns="http://schemas.microsoft.com/2006/mcml"
  xmlns:cor="assembly://MsCorLib/System"
  xmlns:nav="res://Microsoft.MediaCenter.Shell!NavPanel.mcml"
  xmlns:comm="res://Microsoft.MediaCenter.Shell!Globals.mcml"
  xmlns:vid="assembly://ehshell/MediaCenter.Video"
  xmlns:d="res://ehres!DigitEntryView.xml"
  xmlns:play="assembly://ehshell/Microsoft.MediaCenter.Playback"
  xmlns:np="assembly://ehshell/Microsoft.MediaCenter.NowPlaying"
  xmlns:base="res://ehres!InfoBarBase.mcml"
  xmlns:shell="assembly://Microsoft.MediaCenter.Shell/Microsoft.MediaCenter.Shell"
  xmlns:anim="res://Microsoft.MediaCenter.Shell!SlideAnimations.mcml"
  xmlns:me="Me">
  <UI Name="InfoBarHinting" BaseUI="base:InfoBarBase">
    <Properties>
      <vid:InfoBarModel Name="Model" InfoBarModel="$Required"/>
      <np:NowPlayingSlideDeck Name="NowPlaying" NowPlayingSlideDeck="$Required"/>
      <play:MediaNavigator Name="Model1" play:MediaNavigator="$Required"/>
      <play:DigitEntryHelper Name="Helper" play:DigitEntryHelper="$Required"/>
      <play:TunerPolicy Name="TunerPolicy" play:TunerPolicy="null"/>
      <Font Name="PIPFont" FontName="global://comm:MainFontFace" FontSize="28" />
      <Font Name="Font" FontName="global://comm:MainFontFace" FontSize="32" />
      <Color Name="Color" Color="color://comm:OffWhite"/>
      <Color Name="BackColor" Color="color://comm:Transparent"/>
    </Properties>
    <Locals>
      <Environment Name="Environment"/>
      <shell:ShellData Name="ShellData"/>
      <AnchorEdge Name="SafeLeft" Id="Parent" Percent="0"/>
    </Locals>
    <Rules>
      <Rule ConditionLogicalOp="And">
        <Conditions>
          <Equality Source="[Helper.Enabled]" Value="true"/>
          <Equality Source="[Input.DeepKeyFocus]" Value="false"/>
        </Conditions>
        <Actions>
          <Set Target="[DigitEntry.Visible]" Value="true"/>
          <Set Target="[HintingSlide.Visible]" Value="false"/>
        </Actions>
      </Rule>
      <Default Target="[HintingSlide.Visible]" Value="true"/>
      <Default Target="[DigitEntry.Visible]" Value="false"/>
      <Binding Target="[FullChannelNumber.Content]" Source="[Helper.FormattedNumber]"/>
      <Rule ConditionLogicalOp="And">
        <Conditions>
          <Equality Source="[Helper.Submitted]" Value="true"/>
          <IsValid Source="[TunerPolicy]"/>
        </Conditions>
        <Actions>
          <Set Target="[Model1.ChannelNumber]" Value="[TunerPolicy.Number]"/>
          <Set Target="[TunerPolicy.PresetMode]" Value="true"/>
        </Actions>
      </Rule>
      <Rule ConditionLogicalOp="And">
        <Conditions>
          <Equality Source="[Helper.Submitted]" Value="true"/>
          <Equality Source="[TunerPolicy]" ConditionOp="Equals" Value="null"/>
        </Conditions>
        <Actions>
          <Set Target="[Model1.ChannelNumber]" Value="[Helper.Number]"/>
        </Actions>
      </Rule>
      <Condition Source="[Model.CurrentFilter]" SourceValue="" Target="[CurrentFilterIcon.Visible]" Value="false"/>
      <Binding Source="[Model.CurrentFilter]" Target="[CurrentFilterTitle.Content]" />
      <Binding Target="[SafeLeft.Offset]" Source="[ShellData.OverscanMargins.Left]"/>
    </Rules>
    <Content>
      <Panel Layout="Anchor">
        <Children>
          <Panel Name="MainPanel" Layout="Form">
            <Animations>
              <Animation Animation="animation://anim:Infobar.Show" />
              <Animation Animation="animation://anim:Infobar.Hide" />
            </Animations>
            <Children>
              <Panel Name="DigitEntry" Layout="Form" MinimumSize="179,0" MaximumSize="179,0">
                <LayoutInput>
                  <AnchorLayoutInput Left="[SafeLeft]" Top="Outline,0,27"/>
                </LayoutInput>
                <Children>
                  <Text Name="FullChannelNumber" Font="[Font]" Color="[Color]">
                    <LayoutInput>
                      <AnchorLayoutInput Right="Parent,1" Top="Parent,0"/>
                    </LayoutInput>
                  </Text>
                </Children>
              </Panel>
              <Panel Name="HintingSlide" Layout="Form">
                <LayoutInput>
                  <AnchorLayoutInput Left="[SafeLeft]" Top="Outline,0" Bottom="Outline,1"/>
                </LayoutInput>
                <Children>
                  <Panel Name="ChannelInfoPanel" Layout="Form" MinimumSize="120,0">
                    <LayoutInput>
                      <AnchorLayoutInput Right="MediaInfoPanel,0,-12" Top="Parent,0,27"/>
                    </LayoutInput>
                    <Animations>
                      <Animation Animation="animation://comm:MenuItem.HorizontalFaster.Show"/>
                    </Animations>
                    <Children>
                      <d:DigitEntry Name="Channel" EditData="[Model.EditData]" PlayAnimations="false" Font="[TitleFont]" Margins="0,0,0,0">
                        <LayoutInput>
                          <AnchorLayoutInput Right="Parent,1" Top="Parent,0"/>
                        </LayoutInput>
                        <Animations>
                          <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                          <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                        </Animations>
                      </d:DigitEntry>
                      <Text Name="CallSign" Font="[OtherFont]" Color="color://comm:OffWhite" Margins="12,0,0,0">
                        <LayoutInput>
                          <AnchorLayoutInput Right="Parent,1" Top="Channel,1"/>
                        </LayoutInput>
                        <Animations>
                          <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                          <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                        </Animations>
                      </Text>
                      <Panel Name="ChannelInfoIconsPanel">
                        <LayoutInput>
                          <AnchorLayoutInput Right="Channel,0" Top="Channel,0"/>
                        </LayoutInput>
                        <Layout>
                          <FlowLayout Orientation="Horizontal" StopOnEmptyItem="false"/>
                        </Layout>
                        <Children>
                          <Graphic Name="JoinedIcon" Content="res://ehres!InfoBar.TV.Joined.png" Margins="0,11,13,0">
                            <Animations>
                              <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                              <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                            </Animations>
                          </Graphic>
                          <Graphic Name="RecordSeriesIcon" Content="res://ehres!Video.RecordSeries.png" Margins="0,6,13,0">
                            <Animations>
                              <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                              <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                            </Animations>
                          </Graphic>
                          <Graphic Name="RecordSingleIcon" Content="res://ehres!Video.RecordSingle.png" Margins="0,7,13,0">
                            <Animations>
                              <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                              <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                            </Animations>
                          </Graphic>
                        </Children>
                      </Panel>
                    </Children>
                  </Panel>
                  <Graphic Name="DvdIcon" Content="res://ehres!Browse.InsertedCDFocus.png">
                    <LayoutInput>
                      <AnchorLayoutInput Right="MediaInfoPanel,0,-12" Top="Parent,0,27"/>
                    </LayoutInput>
                    <Animations>
                      <Animation Animation="animation://base:InfoBar.Metadata.Show"/>
                      <Animation Animation="animation://base:InfoBar.Metadata.Hide"/>
                    </Animations>
                  </Graphic>
                  <Panel Name="MediaInfoPanel" MaximumSize="1000,0">
                    <LayoutInput>
                      <AnchorLayoutInput Left="Parent,0,191" Top="Parent,0,27" />
                    </LayoutInput>
                    <Layout>
                      <FlowLayout Orientation="Vertical"/>
                    </Layout>
                    <Children>
                      <Text Name="Title" Font="[TitleFont]" Color="color://comm:OffWhite" WordWrap="false"/>
                      <Text Name="SubTitle" Font="[ClockFont]" Color="color://comm:OffWhite" WordWrap="false"/>
                      <Panel Name="TimeInfoPanel" Layout="HorizontalFlow">
                        <Children>
                          <Text Name="TimeInfo" Font="[OtherFont]" Color="color://comm:LightBlue" WordWrap="false"/>
                          <Graphic Name="HDTVIcon" Content="res://ehres!MetaData.HDTV.png" Margins="13, 7, 0, 0"/>
                          <Graphic Name="DolbyDigitalIcon" Content="res://ehres!AudioLogo.png" Margins="17, 7, 0, 0"/>
                        </Children>
                      </Panel>
                      <Panel>
                        <Layout>
                          <FlowLayout Orientation="Horizontal" ItemAlignment="Near"/>
                        </Layout>
                        <Children>
                          <Graphic Name="CurrentFilterIcon" Content="image://me:FavoriteFilterIcon" Visible="true"/>
                          <Text Name="CurrentFilterTitle" Font="[OtherFont]" Color="[OtherColor]"/>
                        </Children>
                      </Panel>
                    </Children>
                  </Panel>
                </Children>
              </Panel>
              <Graphic Content="image://me:BackgroundTopShadow" Name="TopShadow">
                <LayoutInput>
                  <AnchorLayoutInput Top="Parent,0" Left="Parent,0"/>
                </LayoutInput>
              </Graphic>
              <Graphic Content="image://me:Background" Name="Outline">
                <LayoutInput>
                  <AnchorLayoutInput Top="TopShadow,1" Left="Parent,0"/>
                </LayoutInput>
              </Graphic>
            </Children>
          </Panel>
        </Children>
      </Panel>
    </Content>
  </UI>
  <Image Name="Background" Source="res://ehres!NP_Hinting_Background.png" Flippable="true" />
  <Image Name="BackgroundTopShadow" Source="res://ehres!NP_Hinting_Background_TopShd.png" Flippable="true" />
  <Image Name="FavoriteFilterIcon" Image="res://ehres!ChannelBrowser.FavoriteLineup.Icon.png"/>
</Mcml>
You'll also want to replace NP_HINTING_BACKGROUND.PNG by a larger image so that it covers a larger portion of your screen (otherwise, the right part of the program title might be hard to read).
Last edited by Kevin Chalet on Sun Mar 17, 2024 2:33 pm, edited 1 time in total.

User avatar
IT Troll

Posts: 1234
Joined: Sun Nov 27, 2011 9:42 am
Location: Edinburgh, UK

HTPC Specs: Show details

#82

Post by IT Troll » Sun Mar 17, 2024 8:14 am

Media Center Themer is a really excellent tool. It takes a little while to get to grips with it, but once you do, customising things becomes somewhat addictive!
Are you a Recorded TV HD user or want to give it a try? Check out the community-made update; Recorded TV HD v2.1.1

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#83

Post by Kevin Chalet » Sun Mar 17, 2024 3:00 pm

IT Troll wrote: Sun Mar 17, 2024 8:14 am Media Center Themer is a really excellent tool. It takes a little while to get to grips with it, but once you do, customising things becomes somewhat addictive!
100% agree. I was a loooooong-time Media Center Studio user - MCS was working just fine so why changing? :lol: - but I finally gave Media Center Themer a try last year: it makes authoring and deploying themes so much easier!
... and combined with PowerShell remoting, it's insanely easy to sync the theme on all your HTPCs at the same time :twisted:

Engineer

Posts: 10
Joined: Sat Oct 03, 2015 1:46 am
Location:

HTPC Specs: Show details

#84

Post by Engineer » Sun Mar 17, 2024 4:48 pm

Kevin;

Thank you for pointing out Media Center Themer tool and also for providing an example! How I never heard of it before is beyond me ... Just too bad that you do not think very highly of the tool. :D

So while I eat Reuben sandwiches and drink green beer on this St. Patrick's day, I get to play with all this tool can can do!

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#85

Post by Kevin Chalet » Mon Mar 25, 2024 8:13 pm

Engineer wrote: Sun Mar 17, 2024 4:48 pm So while I eat Reuben sandwiches and drink green beer on this St. Patrick's day, I get to play with all this tool can can do!
Did that end well? :mrgreen:

On an unrelated note, I finally updated all my WMC machines - NUCs and homemade HTPCs - last week to adopt the DisableFullscreenOptimizations mini-mod introduced in 1.0.0: after testing it extensively, I was able to confirm that disabling the exclusive fullscreen mode is a very effective way to fix most of - if not all - the graphical issues caused by "HDMI handshakes" (permanent black screens after waking up, weird resolution after unplugging the HDMI cable or waking up, unresponsive GUI, etc.).

I used to rely on MCE Standby to automatically restart WMC (only on machines equipped with Intel iGPUs since NVIDIA and AMD GPUs were much less affected) but it's no longer necessary when using that mod :clap:

prsa01

Posts: 148
Joined: Fri Dec 13, 2019 4:19 pm
Location:

HTPC Specs: Show details

#86

Post by prsa01 » Tue Mar 26, 2024 10:20 am

Kevin Chalet wrote: Mon Mar 25, 2024 8:13 pm
Engineer wrote: Sun Mar 17, 2024 4:48 pm So while I eat Reuben sandwiches and drink green beer on this St. Patrick's day, I get to play with all this tool can can do!
Did that end well? :mrgreen:

On an unrelated note, I finally updated all my WMC machines - NUCs and homemade HTPCs - last week to adopt the DisableFullscreenOptimizations mini-mod introduced in 1.0.0: after testing it extensively, I was able to confirm that disabling the exclusive fullscreen mode is a very effective way to fix most of - if not all - the graphical issues caused by "HDMI handshakes" (permanent black screens after waking up, weird resolution after unplugging the HDMI cable or waking up, unresponsive GUI, etc.).

I used to rely on MCE Standby to automatically restart WMC (only on machines equipped with Intel iGPUs since NVIDIA and AMD GPUs were much less affected) but it's no longer necessary when using that mod :clap:
Cool. I'll give that a try with my wmc black screen on tv power up and report back.

Since winUpdate is known to randomly undo registry settings on occasion, does anyone have a quick/easy way to save & restore specific reg branches such as wmc?

User avatar
IT Troll

Posts: 1234
Joined: Sun Nov 27, 2011 9:42 am
Location: Edinburgh, UK

HTPC Specs: Show details

#87

Post by IT Troll » Tue Mar 26, 2024 10:17 pm

prsa01 wrote: Tue Mar 26, 2024 10:20 am Since winUpdate is known to randomly undo registry settings on occasion, does anyone have a quick/easy way to save & restore specific reg branches such as WMC?
In regedit you can right-click on a branch and export everything from that point down. It exports as a text file which can edit (if desired) and double-click to re-import. Some caution is required though. Some settings are meant to change over time and so re-importing these may have undesirable effects.
Are you a Recorded TV HD user or want to give it a try? Check out the community-made update; Recorded TV HD v2.1.1

prsa01

Posts: 148
Joined: Fri Dec 13, 2019 4:19 pm
Location:

HTPC Specs: Show details

#88

Post by prsa01 » Wed Apr 03, 2024 2:11 pm

I'm sure this SHOULD be readily apparent but just want to make sure my testing plan is based on correct assumptions. I am probably making this more complicated than it is by not fully understanding the process.

If I want to
create all of the reg keys as disabled (or just a few enabled)
turn off/on individual keys for testing
run tests
repeat

I copy one of the all inclusive reg files, edit as necessary, execute
then do I need to restart services and/or reboot to test?
Can I continue to edit that same reg file tweaking on/off and re-execute or is that a bad idea?

This seems, to me, more straightforward than tweaking individual settings in powershell since the reg file will reflect current settings and can be changed/executed. I suppose, now that all the associated reg keys centralized under minimods, it may be just as simple to review/manage them there once they have been created.

Thanks much

User avatar
IT Troll

Posts: 1234
Joined: Sun Nov 27, 2011 9:42 am
Location: Edinburgh, UK

HTPC Specs: Show details

#89

Post by IT Troll » Wed Apr 03, 2024 9:47 pm

If we are just talking about the registry settings associated with minimods, then there is no need to restart services or reboot. Probably best to close Media Center though whilst making changes.

Personally, I would just use regedit to make the entries and for tweaking during the initial testing stage. Once all is as desired, then use the export function to take the backup of your preferences for a quick restore in future.
Are you a Recorded TV HD user or want to give it a try? Check out the community-made update; Recorded TV HD v2.1.1

prsa01

Posts: 148
Joined: Fri Dec 13, 2019 4:19 pm
Location:

HTPC Specs: Show details

#90

Post by prsa01 » Sat Apr 06, 2024 9:40 am

IT Troll wrote: Wed Apr 03, 2024 9:47 pm If we are just talking about the registry settings associated with minimods, then there is no need to restart services or reboot. Probably best to close Media Center though whilst making changes.

Personally, I would just use regedit to make the entries and for tweaking during the initial testing stage. Once all is as desired, then use the export function to take the backup of your preferences for a quick restore in future.
Thanks ITT,

I was making it more complicated than necessary. It all works great. Disabling "full screen optimization" did resolve my black screen on tv on issue.

Thanks much, Kevin for this!

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#91

Post by Kevin Chalet » Sat Apr 06, 2024 7:21 pm

prsa01 wrote: Sat Apr 06, 2024 9:40 am I was making it more complicated than necessary. It all works great. Disabling "full screen optimization" did resolve my black screen on tv on issue.

Thanks much, Kevin for this!
Glad to hear it's working for you too! 8-)
IT Troll wrote: Wed Apr 03, 2024 9:47 pm If we are just talking about the registry settings associated with minimods, then there is no need to restart services or reboot. Probably best to close Media Center though whilst making changes.

Personally, I would just use regedit to make the entries and for tweaking during the initial testing stage. Once all is as desired, then use the export function to take the backup of your preferences for a quick restore in future.
Yeah, it's the simplest option (or you can use Powershell if you're a scripting guy, it works very well too).

You can definitely add/update the mini-mods registry keys while ehshell.exe is still running, but many of the mods will require restarting WMC to be effective (there are exceptions, e.g DisableVideoOverscan only requires stopping/restarting the TV stream, e.g by switching to a different channel).

prsa01

Posts: 148
Joined: Fri Dec 13, 2019 4:19 pm
Location:

HTPC Specs: Show details

#92

Post by prsa01 » Sun Apr 07, 2024 10:23 am

Kevin, is it possible to allow minimizing while DisableWindowedMode is on? I'm guessing not but figured I'd confirm. Confuses the better half.

Not a big deal. She'll figure out alt-tab eventually.

Thanks again for some great wmc usability improvements!

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#93

Post by Kevin Chalet » Sun Apr 07, 2024 3:20 pm

prsa01 wrote: Sun Apr 07, 2024 10:23 am Kevin, is it possible to allow minimizing while DisableWindowedMode is on? I'm guessing not but figured I'd confirm. Confuses the better half.
Sadly no. I personally only use DisableWindowedMode on my WMC-dedicated machines (they are only used with MCE remotes, so not having a windowed mode is not a concern at all). For my "hybrid" machines, I don't use it: when booting these machines, WMC doesn't go fullscreen automatically, but since I rarely restart them (I'm an hibernation guy :mrgreen:), it's not really a big deal either.
prsa01 wrote: Sun Apr 07, 2024 10:23 am Thanks again for some great WMC usability improvements!
My pleasure!

packetloss

Posts: 17
Joined: Mon Mar 06, 2017 3:00 pm
Location: Massapequa

HTPC Specs: Show details

#94

Post by packetloss » Mon Apr 08, 2024 1:39 am

I've been stuck in the PlayReady update loop and have been trying to find a solution and eventually came across this thread.
From what I've seen in threads, you don't use a CableCard since that is only a US thing. What happens when trying to set up the tuners for use with a CableCard is:
1 - you need to run Digital Advisor. This still works fine.
2 - you need PlayReady (there are 2 versions 1.3.0 and 1.3.10) that are available to install, issue happens with either version. My original W7 WMC is running fine with 1.3.0.
3 - When you go through the tuner setup it eventually comes to a screen where it wants to update PlayReady but can't and complains that you don't have an internet connection and do you want to try again. This apparently fails as the MS server for this update is no longer active.

I am hoping a simple override to this check will allow the tuner setup to complete and that PlayReady will get configured and work. There were some guides suggesting deleting the DRM files from ehome, etc. etc., but none of those really work.

I don't know enough about how WMC libraries work, but it seems like perhaps patching this routine to always return true might work. Ideally, I would want whatever routine that wants to check for an update, to just return success. Just not sure if this is the right place as this doesn't seem to be checking to see if a new version is available. I will have to put a W10 1511 build back together to test this (I trashed it after I couldn't get past the PlayReady update loop), but before I do, I figured I'd see if you had any thoughts as to whether this seems like the right place to patch it or if you might be able to point me to the spot that looks like it's checking to see if a newer version is available and doing the update.

namespace Microsoft.MediaCenter
{
protected override bool IsOfficiallyInstalled
{
get
{
Version v = new Version("1.3.0");
Version version = new Version("0.0");
int num = 50;
StringBuilder stringBuilder = new StringBuilder(50);
uint num2 = 0U;
while (PlayReadyInstaller.MsiEnumClientsW("{63EBD4FD-72C1-49A6-86F1-CCD300FB9532}", num2++, stringBuilder, ref num) == 0U)
{
num = 50;
string text = stringBuilder.ToString();
if (!string.IsNullOrEmpty(text))
{
int num3 = 50;
StringBuilder stringBuilder2 = new StringBuilder(50);
if (PlayReadyInstaller.MsiGetProductInfoW(text, "VersionString", stringBuilder2, ref num3) == 0U)
{
string text2 = stringBuilder2.ToString();
if (!string.IsNullOrEmpty(text2))
{
Version version2;
if (text2.IndexOf('.') == -1)
{
version2 = new Version(Convert.ToInt32(text2, CultureInfo.InvariantCulture), 0);
}
else
{
version2 = new Version(text2);
}
if (version2 > version)
{
version = version2;
}
}
}
}
}
return version >= v;
}
}
}

User avatar
garyan2

Posts: 7533
Joined: Fri Nov 27, 2015 7:23 pm
Location:

HTPC Specs: Show details

#95

Post by garyan2 » Mon Apr 08, 2024 4:05 am

packetloss wrote: Mon Apr 08, 2024 1:39 am I will have to put a W10 1511 build back together to test this (I trashed it after I couldn't get past the PlayReady update loop), but before I do, I figured I'd see if you had any thoughts as to whether this seems like the right place to patch it or if you might be able to point me to the spot that looks like it's checking to see if a newer version is available and doing the update.
If you're going to build a new Win10 1511 WMC, try this method to see if that works. viewtopic.php?p=153329#p153329
- Gary
Keeping WMC alive beyond January 2020. https://garyan2.github.io

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#96

Post by Kevin Chalet » Sun Jul 21, 2024 9:28 pm

New 2.8.0 release:

ehshell.dll patches:

8K UHD support for the existing EnableExtendedContentSizeCorrection hook:

WMC mini-mods 2.4.0 introduced a new EnableExtendedContentSizeCorrection hook that extends the content size correction algorithm introduced a while ago by Microsoft - see viewtopic.php?t=14526&start=40#p153086 for more information - to support 4K UHD displays.
WMC mini-mods 2.8.0 patches ehshell.dll to also apply the same logic to 8K UHD - i.e 7680x4320 - screens :mrgreen:

Code: Select all

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Threading;
using ehiExtCOM;
using EHMedia;
using MediaCenter.Extensibility;
using MediaCenter.ListMaker;
using Microsoft.MediaCenter.Debug;
using Microsoft.MediaCenter.Hosting.Infrastructure;
using Microsoft.MediaCenter.Interop;
using Microsoft.MediaCenter.Playback;
using Microsoft.MediaCenter.Shell;
using Microsoft.MediaCenter.UI;
using Microsoft.MediaCenter.UI.Drawing;
using Microsoft.MediaCenter.UI.VideoPlayback;
using Microsoft.MediaCenter.Utility;
using Microsoft.Win32;

namespace ServiceBus.UIFramework
{
    // Token: 0x02000B4F RID: 2895
    internal sealed partial class PageBasedUCPService : UCPService, IUsageLogger, IUIVideoStreamBroker
    {
        // Token: 0x060067BE RID: 26558 RVA: 0x001A7F98 File Offset: 0x001A6198
        private void UpdateContentSize(Size logicalSize, Size physicalSize)
        {
            if (this._rootGadget != null)
            {
                Rectangle rectangle = new Rectangle(0, 0, logicalSize.Width, logicalSize.Height);
                SizeF sizeF;
                if (this.ComputeUsableArea(ref rectangle, out sizeF, this.Form.WindowState, false))
                {
                    float num = Math.Min(sizeF.Width, sizeF.Height);
                    Vector3 vector = new Vector3(num, num, num);
                    this.NotificationPanel.IdealLeft = rectangle.Left;
                    this.NotificationPanel.IdealTop = rectangle.Top;
                    Size size = rectangle.Size;
                    Size size2 = new Size((int)Math.Round((double)((float)size.Width / vector.X)), (int)Math.Round((double)((float)size.Height / vector.Y)));

                    if (this.Form.WindowState == FormWindowState.Maximized && size2.Width == 1365 && size2.Height == 768)
                    {
                        if (size.Width == 1920 && size.Height == 1080)
                        {
                            size2.Width = 1366;
                        }

                        else
                        {
                            using var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center\\MiniMods");
                            if (key is not null && key.GetValue("EnableExtendedContentSizeCorrection") is 1)
                            {
                                if (size.Width is 3840 && size.Height is 2160)
                                {
                                    size2.Width = 1366;
                                }
                                else if (size.Width is 7680 && size.Height is 4320)
                                {
                                    size2.Width = 1366;
                                }
                            }
                        }
                    }

                    bool flag = this.IsWidescreen();
                    this.NotificationPanel.IdealWidth = size2.Width;
                    this.NotificationPanel.IdealHeight = size2.Height;
                    if (ListMakerUtility.ProgressBar != null)
                    {
                        ListMakerUtility.ProgressBar.Apply16X9();
                    }
                    bool flag2 = this.IsWidescreen();
                    if (flag != flag2)
                    {
                        Microsoft.MediaCenter.UI.Environment environment = Microsoft.MediaCenter.UI.Environment.Get(this._session);
                        if (environment != null)
                        {
                            environment.SetWidescreen(flag2);
                        }
                        if (this.IsWidescreenChangedHandler != null)
                        {
                            this.IsWidescreenChangedHandler(flag2);
                        }
                    }
                    if (!logicalSize.IsEmpty)
                    {
                        if (physicalSize != logicalSize)
                        {
                            vector.X *= (float)physicalSize.Width / (float)logicalSize.Width;
                            vector.Y *= (float)physicalSize.Height / (float)logicalSize.Height;
                        }
                        this._session.OutputDevice.FlushFontCache();
                        this._sizefContentScale = new SizeF(vector.X, vector.Y);
                        this.NotificationPanel.Scale = vector;
                        if (this.Form.WindowState == FormWindowState.Maximized)
                        {
                            this.RootGadget.ToolbarRoot.IdealWidth = size2.Width;
                            this.RootGadget.ToolbarRoot.IdealHeight = size2.Height;
                            this.RootGadget.ToolbarRoot.Margin = this.UserConfig.OverscanMargins;
                            this.RootGadget.ToolbarRoot.Scale = vector;
                            this.Toolbars.TwoFootToolBar.ToolBarData.EnableMiniTransportToolbar = false;
                            this.Toolbars.TwoFootToolBar.ToolBarData.AllowItvToolbar = true;
                        }
                        else
                        {
                            float num2 = 0.85f;
                            Vector3 vector2;
                            if (vector.X >= num2)
                            {
                                vector2 = vector;
                            }
                            else
                            {
                                vector2 = new Vector3(num2, num2, num2);
                            }
                            this.RootGadget.ToolbarRoot.IdealWidth = (int)Math.Round((double)((float)physicalSize.Width / vector2.X));
                            this.RootGadget.ToolbarRoot.IdealHeight = (int)Math.Round((double)((float)physicalSize.Height / vector2.Y));
                            this.RootGadget.ToolbarRoot.Margin = Inset.Empty;
                            this.RootGadget.ToolbarRoot.Scale = vector2;
                            if (physicalSize.Width < 790)
                            {
                                this.Toolbars.TwoFootToolBar.ToolBarData.EnableMiniTransportToolbar = true;
                            }
                            else
                            {
                                this.Toolbars.TwoFootToolBar.ToolBarData.EnableMiniTransportToolbar = false;
                            }
                            if (physicalSize.Width < 850)
                            {
                                this.Toolbars.TwoFootToolBar.ToolBarData.AllowItvToolbar = false;
                            }
                            else
                            {
                                this.Toolbars.TwoFootToolBar.ToolBarData.AllowItvToolbar = true;
                            }
                        }
                        if (this.IdealSizeChangedHandler != null)
                        {
                            this.IdealSizeChangedHandler(this.NotificationPanel.IdealWidth.Value, this.NotificationPanel.IdealHeight.Value);
                        }
                    }
                }
                this._rcUsableContent = rectangle;
            }
        }
    }
}

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\MiniMods]
"EnableExtendedContentSizeCorrection"=dword:00000001
You do not have the required permissions to view the files attached to this post.

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#97

Post by Kevin Chalet » Mon Jul 22, 2024 4:23 pm

New 2.9.0 release:

Microsoft.MediaCenter.UI.dll patches:

Option to limit the maximum scale used by Microsoft.MediaCenter.UI.Drawing.RichText:

While WMC runs absolutely fine on a 1080p display, using a 4K - or worse, an 8K display - can cause visual issues affecting text rendering (e.g the text is truncated or the fading effect is not properly applied).

It's generally bearable on a 4K display...
WMC 4K.png
... but not really on a 8K one (I had to resize the screenshot to be below TGB's upload limit): here, the program description is severely truncated - it's even completely unreadable - and program titles are also affected (they are not properly centered and some are cut off).
WMC 8K.png
This strange behavior seems to be caused by a limitation in Microsoft.MediaCenter.UI.Drawing.RichText (or more likely the underlying unmanaged RTF implementation): as soon as the text scale becomes too high (e.g when it's running full screen on a 4K display), visual issues start to appear pretty much everywhere.

To avoid that, WMC Mini-Mods 2.9.0 introduces a new RichTextScaleLimit that allows limiting the maximum scale WMC can set.

Code: Select all

using System;
using System.Collections;
using System.ComponentModel;
using Microsoft.MediaCenter.UI.Drawing;
using Microsoft.Win32;

namespace Microsoft.MediaCenter.UI
{
    // Token: 0x020001DE RID: 478
    [MarkupVisible]
    internal partial class Text : ViewItem, ILayout
    {
        // Token: 0x06001359 RID: 4953 RVA: 0x0004F918 File Offset: 0x0004DB18
        void ILayout.Layout(ILayoutParentAgent laSubject, Constraint constraint, out Size sizeUsed)
        {
            if (this.m_stContent == null)
            {
                sizeUsed = constraint.Min;
                return;
            }
            HorizontalAlignment horizontalAlignment = RichText.ReverseAlignment(this.m_alignHoriz, this.m_fTextIsRtl);
            if (this.m_flow == null || laSubject.ReasonForLayout != LayoutReason.ViewingRectangleChanged)
            {
                string fontName = this.m_font.FontName;
                int num = (int)Math.Round((double)this.m_font.FontSize);
                bool flag = (this.m_font.FontStyle & FontStyles.Bold) != FontStyles.None;
                bool flag2 = (this.m_font.FontStyle & FontStyles.Italic) != FontStyles.None;
                Text.s_rtShared.SetFormat(fontName, num, this.m_crText, flag, flag2, this.m_fWordWrap, horizontalAlignment, this.m_fTextIsRtl);
                Text.s_rtShared.Content = this.m_stContent;

                using var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center\\MiniMods");
                if (key is not null && key.GetValue("RichTextScaleLimit") is int value)
                {
                    var scale = this.m_flScale;
                    var limit = (float) (value / 1000);
                    Text.s_rtShared.Scale = scale > limit ? limit : scale;
                }
                else
                {
                    Text.s_rtShared.Scale = this.m_flScale;
                }

                SizeF sizeF = new SizeF(4095f, 8191f);
                if (this.m_fWordWrap)
                {
                    sizeF.Width = Math.Min((float)constraint.Max.Width, sizeF.Width);
                }
                Text.s_rtShared.Constraint = sizeF;
                this.m_flow = Text.s_rtShared.Measure();
            }
            else
            {
                this.m_flow.ResetFitTracking();
                this.m_flow.ResetVisibleTracking();
            }
            this.m_fKeepFlowAlive = this.m_fWordWrap && constraint.IsViewBoundsSpecified;
            bool flag3 = this.m_flow.Bounds.Width > (float)constraint.Max.Width;
            bool flag4 = this.m_flow.Bounds.Height > (float)constraint.Max.Height;
            bool flag5 = this.m_flow.Bounds.Width < (float)constraint.Min.Width;
            PointF pointF = new PointF(this.m_flow.Bounds.Location.X * -1f, this.m_flow.Bounds.Location.Y * -1f);
            if (flag3 || flag5)
            {
                float num2;
                if (flag3)
                {
                    num2 = (float)constraint.Max.Width - this.m_flow.Bounds.Width;
                }
                else
                {
                    num2 = (float)constraint.Min.Width - this.m_flow.Bounds.Width;
                }
                switch (horizontalAlignment)
                {
                case HorizontalAlignment.Center:
                    pointF.X += num2 / 2f;
                    break;
                case HorizontalAlignment.Far:
                    pointF.X += num2;
                    break;
                }
            }
            sizeUsed = constraint.Clamp(new Size((int)Math.Ceiling((double)this.m_flow.Bounds.Width), (int)Math.Ceiling((double)this.m_flow.Bounds.Height)));
            this.m_nRunClipVertical = -1;
            int num3 = -1;
            float num4 = 0f;
            float num5 = 0f;
            PointF pointF2 = new PointF(pointF.X, pointF.Y);
            for (int i = 0; i < this.m_flow.Count; i++)
            {
                TextRun textRun = this.m_flow[i];
                if (textRun.Line > this.MaximumLines)
                {
                    flag4 = true;
                    break;
                }
                if (this.m_fAdjustLineSpacingByContentBounds)
                {
                    if (textRun.Line != num3)
                    {
                        num4 = num5;
                        num3 = textRun.Line;
                    }
                    pointF2.X = pointF.X;
                    pointF2.Y = pointF.Y;
                    pointF2.Y -= textRun.ContentBounds.Y - num4;
                    pointF2.Y += this.m_flAdditionalLineSpacingAdjustment;
                }
                textRun.ApplyOffset(pointF2);
                if (this.m_fAdjustLineSpacingByContentBounds && textRun.ContentBounds.Bottom - pointF.Y > num5)
                {
                    num5 = textRun.ContentBounds.Bottom - pointF.Y;
                }
                if (textRun.ContentBounds.Bottom > (float)constraint.Max.Height)
                {
                    if (textRun.Line != 1)
                    {
                        break;
                    }
                    if (this.m_nRunClipVertical == -1)
                    {
                        this.m_nRunClipVertical = constraint.Max.Height;
                    }
                }
                this.m_flow.AddFit(textRun);
                if (textRun.LogicalBounds.IntersectsWith(constraint.PeripheralView))
                {
                    this.m_flow.AddVisible(i);
                }
            }
            this.m_fTextFitsWidth = this.m_fWordWrap || !flag3;
            this.m_fTextFitsHeight = !flag4;
            this.CreateFadeGradients(laSubject);
            sizeUsed = constraint.Clamp(new Size((int)Math.Ceiling((double)this.m_flow.Bounds.Width), (int)Math.Ceiling((double)this.m_flow.FitBounds.Height)));
            Size size;
            DefaultLayout.Layout(laSubject, new Constraint(sizeUsed), out size);
        }
    }
}
Empirically, I was able to determine that the value "2999" (converted to 2.999 internally) is the best compromise between the text starting to become a bit blurry and being affected by visual glitches:
WMC fixed.png

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\MiniMods]
"RichTextScaleLimit"=dword:00000bb7
You do not have the required permissions to view the files attached to this post.

User avatar
IT Troll

Posts: 1234
Joined: Sun Nov 27, 2011 9:42 am
Location: Edinburgh, UK

HTPC Specs: Show details

#98

Post by IT Troll » Mon Jul 22, 2024 8:25 pm

Wow, 8K Media Center!

I'm not sure why you would, but certainly cool that you made it possible.
Are you a Recorded TV HD user or want to give it a try? Check out the community-made update; Recorded TV HD v2.1.1

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#99

Post by Kevin Chalet » Tue Jul 23, 2024 10:47 am

IT Troll wrote: Mon Jul 22, 2024 8:25 pm I'm not sure why you would, but certainly cool that you made it possible.
It's certainly a niche, but I can see two use cases for 8K:
  • When you have an 8K TV (tho' they are still quite rare)
  • When you have a 4K display and are using x4 Dynamic Super Resolution (i.e 8K UHD).
Anyway, that mod also helps with 4K. 8K support is just a cool bonus :mrgreen:

User avatar
Kevin Chalet

Posts: 190
Joined: Mon Oct 08, 2018 12:00 pm
Location:

HTPC Specs: Show details

#100

Post by Kevin Chalet » Tue Aug 13, 2024 4:05 pm

Kevin Chalet wrote: Sun Mar 17, 2024 1:15 am Changing the "skin files" is out of scope for this project - which exclusively focuses on patching the WMC .NET assemblies - but it's fairly easy to customize that yourself.
For that, you can use the excellent/fantastic/magical/impressive/incredible Media Center Themer tool: https://www.thegreenbutton.tv/wiki/inde ... ter_Themer :mrgreen:
I opened a separate thread dedicated to resource modding: viewtopic.php?t=14770.

Please don't hesitate to share your tweaks! :prayer:

Post Reply