├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Controls
├── CustomColorsRenderer.cs
└── CustomComboBox.cs
├── Docs
└── ToDo_Ideas.txt
├── Forms
├── DateForm.cs
├── DateForm.designer.cs
├── DateForm.resx
├── MessageForm.Designer.cs
├── MessageForm.cs
├── MessageForm.resx
└── WeekNumberForDateForm.cs
├── IGui.cs
├── IconSize.cs
├── Installation
├── License.de-DE.txt
├── License.en-US.txt
└── License.sv-SE.txt
├── LICENSE
├── Log.cs
├── Message.cs
├── NativeMethods.cs
├── Program.cs
├── Properties
├── App.config
├── AssemblyInfo.cs
├── WeekNumber.snk
└── app.manifest
├── README.de-DE.md
├── README.md
├── README.sv-SE.md
├── Resources
├── Resources.Designer.cs
├── Resources.de-DE.Designer.cs
├── Resources.de-DE.resx
├── Resources.en-US.Designer.cs
├── Resources.en-US.resx
├── Resources.resx
├── Resources.sv-SE.Designer.cs
├── Resources.sv-SE.resx
├── WeekNumber.bmp
├── infoIconWhite.png
└── weekicon.ico
├── SECURITY.md
├── Settings.cs
├── TaskbarGui.cs
├── TaskbarUtil.cs
├── Tools
└── fart199b_win32.zip
├── Week.cs
├── WeekApplicationContext.cs
├── WeekIcon.cs
├── WeekNumber.csproj
├── WeekNumber.sln
├── WeekNumberContextMenu.cs
├── WeekNumberMonitor
├── AssemblyInfo.cs
├── Program.cs
├── WeekNumber.snk
├── WeekNumberMonitor.csproj
└── app.config
├── _config.yml
├── app.config
└── build.bat
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: voltura
2 | custom: ["https://www.paypal.me/voltura"]
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 |
2 | # supported CodeQL languages.
3 | #
4 | name: "CodeQL"
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | # The branches below must be a subset of the branches above
11 | branches: [ master ]
12 | schedule:
13 | - cron: '23 18 * * 5'
14 |
15 | jobs:
16 | analyze:
17 | name: Analyze
18 | runs-on: windows-2019
19 | permissions:
20 | actions: write
21 | contents: write
22 | security-events: write
23 |
24 | strategy:
25 | fail-fast: false
26 | matrix:
27 | language: [ 'csharp' ]
28 |
29 | steps:
30 | - name: Checkout repository
31 | uses: actions/checkout@v2
32 |
33 | # Initializes the CodeQL tools for scanning.
34 | - name: Initialize CodeQL
35 | uses: github/codeql-action/init@v1
36 | with:
37 | languages: ${{ matrix.language }}
38 | # Add msbuild
39 | - name: Add msbuild to PATH
40 | uses: microsoft/setup-msbuild@v1.0.2
41 | with:
42 | vs-version: '[16.11,)'
43 | # make release
44 |
45 | - name: Release build
46 | run: msbuild WeekNumber.sln /p:Platform=x86 /property:Configuration=Release -m
47 | shell: cmd
48 |
49 | - name: Debug clean build
50 | run: msbuild WeekNumber.sln /t:rebuild
51 |
52 | - name: Autobuild
53 | uses: github/codeql-action/autobuild@v1
54 |
55 | - name: Perform CodeQL Analysis
56 | uses: github/codeql-action/analyze@v1
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 | *.log
13 |
14 | # User-specific files (MonoDevelop/Xamarin Studio)
15 | *.userprefs
16 |
17 | # Mono auto generated files
18 | mono_crash.*
19 |
20 | # Build results
21 | [Dd]ebug/
22 | [Dd]ebugPublic/
23 | [Rr]elease/
24 | [Rr]eleases/
25 | x64/
26 | x86/
27 | [Ww][Ii][Nn]32/
28 | [Aa][Rr][Mm]/
29 | [Aa][Rr][Mm]64/
30 | bld/
31 | [Bb]in/
32 | [Oo]bj/
33 | [Oo]ut/
34 | [Ll]og/
35 | [Ll]ogs/
36 |
37 | # Visual Studio 2015/2017 cache/options directory
38 | .vs/
39 | # Uncomment if you have tasks that create the project's static files in wwwroot
40 | #wwwroot/
41 |
42 | # Visual Studio 2017 auto generated files
43 | Generated\ Files/
44 |
45 | # MSTest test Results
46 | [Tt]est[Rr]esult*/
47 | [Bb]uild[Ll]og.*
48 |
49 | # NUnit
50 | *.VisualState.xml
51 | TestResult.xml
52 | nunit-*.xml
53 |
54 | # Build Results of an ATL Project
55 | [Dd]ebugPS/
56 | [Rr]eleasePS/
57 | dlldata.c
58 |
59 | # Benchmark Results
60 | BenchmarkDotNet.Artifacts/
61 |
62 | # .NET Core
63 | project.lock.json
64 | project.fragment.lock.json
65 | artifacts/
66 |
67 | # ASP.NET Scaffolding
68 | ScaffoldingReadMe.txt
69 |
70 | # StyleCop
71 | StyleCopReport.xml
72 |
73 | # Files built by Visual Studio
74 | *_i.c
75 | *_p.c
76 | *_h.h
77 | *.ilk
78 | *.meta
79 | *.obj
80 | *.iobj
81 | *.pch
82 | *.pdb
83 | *.ipdb
84 | *.pgc
85 | *.pgd
86 | *.rsp
87 | *.sbr
88 | *.tlb
89 | *.tli
90 | *.tlh
91 | *.tmp
92 | *.tmp_proj
93 | *_wpftmp.csproj
94 | *.log
95 | *.vspscc
96 | *.vssscc
97 | .builds
98 | *.pidb
99 | *.svclog
100 | *.scc
101 |
102 | # Chutzpah Test files
103 | _Chutzpah*
104 |
105 | # Visual C++ cache files
106 | ipch/
107 | *.aps
108 | *.ncb
109 | *.opendb
110 | *.opensdf
111 | *.sdf
112 | *.cachefile
113 | *.VC.db
114 | *.VC.VC.opendb
115 |
116 | # Visual Studio profiler
117 | *.psess
118 | *.vsp
119 | *.vspx
120 | *.sap
121 |
122 | # Visual Studio Trace Files
123 | *.e2e
124 |
125 | # TFS 2012 Local Workspace
126 | $tf/
127 |
128 | # Guidance Automation Toolkit
129 | *.gpState
130 |
131 | # ReSharper is a .NET coding add-in
132 | _ReSharper*/
133 | *.[Rr]e[Ss]harper
134 | *.DotSettings.user
135 |
136 | # TeamCity is a build add-in
137 | _TeamCity*
138 |
139 | # DotCover is a Code Coverage Tool
140 | *.dotCover
141 |
142 | # AxoCover is a Code Coverage Tool
143 | .axoCover/*
144 | !.axoCover/settings.json
145 |
146 | # Coverlet is a free, cross platform Code Coverage Tool
147 | coverage*.json
148 | coverage*.xml
149 | coverage*.info
150 |
151 | # Visual Studio code coverage results
152 | *.coverage
153 | *.coveragexml
154 |
155 | # NCrunch
156 | _NCrunch_*
157 | .*crunch*.local.xml
158 | nCrunchTemp_*
159 |
160 | # MightyMoose
161 | *.mm.*
162 | AutoTest.Net/
163 |
164 | # Web workbench (sass)
165 | .sass-cache/
166 |
167 | # Installshield output folder
168 | [Ee]xpress/
169 |
170 | # DocProject is a documentation generator add-in
171 | DocProject/buildhelp/
172 | DocProject/Help/*.HxT
173 | DocProject/Help/*.HxC
174 | DocProject/Help/*.hhc
175 | DocProject/Help/*.hhk
176 | DocProject/Help/*.hhp
177 | DocProject/Help/Html2
178 | DocProject/Help/html
179 |
180 | # Click-Once directory
181 | publish/
182 |
183 | # Publish Web Output
184 | *.[Pp]ublish.xml
185 | *.azurePubxml
186 | # Note: Comment the next line if you want to checkin your web deploy settings,
187 | # but database connection strings (with potential passwords) will be unencrypted
188 | *.pubxml
189 | *.publishproj
190 |
191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
192 | # checkin your Azure Web App publish settings, but sensitive information contained
193 | # in these scripts will be unencrypted
194 | PublishScripts/
195 |
196 | # NuGet Packages
197 | *.nupkg
198 | # NuGet Symbol Packages
199 | *.snupkg
200 | # The packages folder can be ignored because of Package Restore
201 | **/[Pp]ackages/*
202 | # except build/, which is used as an MSBuild target.
203 | !**/[Pp]ackages/build/
204 | # Uncomment if necessary however generally it will be regenerated when needed
205 | #!**/[Pp]ackages/repositories.config
206 | # NuGet v3's project.json files produces more ignorable files
207 | *.nuget.props
208 | *.nuget.targets
209 |
210 | # Microsoft Azure Build Output
211 | csx/
212 | *.build.csdef
213 |
214 | # Microsoft Azure Emulator
215 | ecf/
216 | rcf/
217 |
218 | # Windows Store app package directories and files
219 | AppPackages/
220 | BundleArtifacts/
221 | Package.StoreAssociation.xml
222 | _pkginfo.txt
223 | *.appx
224 | *.appxbundle
225 | *.appxupload
226 |
227 | # Visual Studio cache files
228 | # files ending in .cache can be ignored
229 | *.[Cc]ache
230 | # but keep track of directories ending in .cache
231 | !?*.[Cc]ache/
232 |
233 | # Others
234 | ClientBin/
235 | ~$*
236 | *~
237 | *.dbmdl
238 | *.dbproj.schemaview
239 | *.jfm
240 | *.pfx
241 | *.publishsettings
242 | orleans.codegen.cs
243 |
244 | # Including strong name files can present a security risk
245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
246 | #*.snk
247 |
248 | # Since there are multiple workflows, uncomment next line to ignore bower_components
249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
250 | #bower_components/
251 |
252 | # RIA/Silverlight projects
253 | Generated_Code/
254 |
255 | # Backup & report files from converting an old project file
256 | # to a newer Visual Studio version. Backup files are not needed,
257 | # because we have git ;-)
258 | _UpgradeReport_Files/
259 | Backup*/
260 | UpgradeLog*.XML
261 | UpgradeLog*.htm
262 | ServiceFabricBackup/
263 | *.rptproj.bak
264 |
265 | # SQL Server files
266 | *.mdf
267 | *.ldf
268 | *.ndf
269 |
270 | # Business Intelligence projects
271 | *.rdl.data
272 | *.bim.layout
273 | *.bim_*.settings
274 | *.rptproj.rsuser
275 | *- [Bb]ackup.rdl
276 | *- [Bb]ackup ([0-9]).rdl
277 | *- [Bb]ackup ([0-9][0-9]).rdl
278 |
279 | # Microsoft Fakes
280 | FakesAssemblies/
281 |
282 | # GhostDoc plugin setting file
283 | *.GhostDoc.xml
284 |
285 | # Node.js Tools for Visual Studio
286 | .ntvs_analysis.dat
287 | node_modules/
288 |
289 | # Visual Studio 6 build log
290 | *.plg
291 |
292 | # Visual Studio 6 workspace options file
293 | *.opt
294 |
295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
296 | *.vbw
297 |
298 | # Visual Studio LightSwitch build output
299 | **/*.HTMLClient/GeneratedArtifacts
300 | **/*.DesktopClient/GeneratedArtifacts
301 | **/*.DesktopClient/ModelManifest.xml
302 | **/*.Server/GeneratedArtifacts
303 | **/*.Server/ModelManifest.xml
304 | _Pvt_Extensions
305 |
306 | # Paket dependency manager
307 | .paket/paket.exe
308 | paket-files/
309 |
310 | # FAKE - F# Make
311 | .fake/
312 |
313 | # CodeRush personal settings
314 | .cr/personal
315 |
316 | # Python Tools for Visual Studio (PTVS)
317 | __pycache__/
318 | *.pyc
319 |
320 | # Cake - Uncomment if you are using it
321 | # tools/**
322 | # !tools/packages.config
323 |
324 | # Tabs Studio
325 | *.tss
326 |
327 | # Telerik's JustMock configuration file
328 | *.jmconfig
329 |
330 | # BizTalk build output
331 | *.btp.cs
332 | *.btm.cs
333 | *.odx.cs
334 | *.xsd.cs
335 |
336 | # OpenCover UI analysis results
337 | OpenCover/
338 |
339 | # Azure Stream Analytics local run output
340 | ASALocalRun/
341 |
342 | # MSBuild Binary and Structured Log
343 | *.binlog
344 |
345 | # NVidia Nsight GPU debugger configuration file
346 | *.nvuser
347 |
348 | # MFractors (Xamarin productivity tool) working folder
349 | .mfractor/
350 |
351 | # Local History for Visual Studio
352 | .localhistory/
353 |
354 | # BeatPulse healthcheck temp database
355 | healthchecksdb
356 |
357 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
358 | MigrationBackup/
359 |
360 | # Ionide (cross platform F# VS Code tools) working folder
361 | .ionide/
362 |
363 | # Fody - auto-generated XML schema
364 | FodyWeavers.xsd
365 | /Tools/fart.exe
366 | GITHUB_ACCESS_TOKEN.bat
367 | CreateGithubRelease.bat
368 | /Tools/curl-7.76.1_2-win64-mingw.zip
369 | curl_examples.txt
370 | GITHUB_ACCESS_TOKEN.bat
371 | /Tools/curl-7.84.0_4-win64-mingw.zip
372 | release_info.txt
373 | /NSIS Installation/Plugins
374 | /NSIS Installation/CompileInstaller.bat
375 | /NSIS Installation/WeekNumber.nsi
376 | /Installation/CompileInstaller.bat
377 | /Installation/WeekNumber.nsi
378 | /Installation/Plugins
379 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | weeknumber@voltura.se.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Feel free to fork this branch and contribute to the application by modifications or additions to its logic, all merge requests will be evaluated and if deemed fit merged into the master branch/included in future release
2 |
--------------------------------------------------------------------------------
/Controls/CustomColorsRenderer.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | #endregion
7 |
8 | namespace WeekNumber.Controls
9 | {
10 | ///
11 | /// Customize menu item selected colors
12 | ///
13 | public class CustomColorsRenderer : ToolStripProfessionalRenderer
14 | {
15 | #region Constructor
16 |
17 | ///
18 | /// Constructor
19 | ///
20 | public CustomColorsRenderer() : base(new CustomColors())
21 | {
22 | }
23 |
24 | #endregion
25 |
26 | #region Private class
27 |
28 | private class CustomColors : ProfessionalColorTable
29 | {
30 | public override Color MenuItemSelected => Color.DeepSkyBlue;
31 |
32 | public override Color MenuItemSelectedGradientBegin => Color.DeepSkyBlue;
33 |
34 | public override Color MenuItemSelectedGradientEnd => Color.DeepSkyBlue;
35 | }
36 |
37 | #endregion
38 | }
39 | }
--------------------------------------------------------------------------------
/Controls/CustomComboBox.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | #endregion
7 |
8 | namespace WeekNumber.Controls
9 | {
10 | ///
11 | /// Combobox with custom colors
12 | ///
13 | public class CustomComboBox : ComboBox
14 | {
15 | #region Public properties
16 |
17 | ///
18 | /// DrawMode
19 | ///
20 | public new DrawMode DrawMode { get; set; }
21 |
22 | ///
23 | /// Highlight color
24 | ///
25 | public Color HighlightColor { get; set; }
26 |
27 | #endregion
28 |
29 | #region Public constructor
30 |
31 | ///
32 | /// Constructor, sets highlight color
33 | ///
34 | public CustomComboBox()
35 | {
36 | base.DrawMode = DrawMode.OwnerDrawFixed;
37 | HighlightColor = Color.DeepSkyBlue;
38 | DrawItem += CustomComboBox_DrawItem;
39 | }
40 |
41 | #endregion
42 |
43 | #region Private methods
44 |
45 | private void CustomComboBox_DrawItem(object sender, DrawItemEventArgs e)
46 | {
47 | if (e.Index < 0)
48 | {
49 | return;
50 | }
51 |
52 | ComboBox combo = sender as ComboBox;
53 | if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
54 | {
55 | using (SolidBrush brush = new SolidBrush(HighlightColor))
56 | {
57 | e.Graphics.FillRectangle(brush, e.Bounds);
58 | }
59 | }
60 | else if (combo != null)
61 | {
62 | using (SolidBrush brush = new SolidBrush(combo.BackColor))
63 | {
64 | e.Graphics.FillRectangle(brush, e.Bounds);
65 | }
66 | }
67 |
68 | if (combo != null)
69 | {
70 | using (SolidBrush brush = new SolidBrush(combo.ForeColor))
71 | {
72 | e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font,
73 | brush, new Point(e.Bounds.X, e.Bounds.Y));
74 | }
75 | }
76 |
77 | e.DrawFocusRectangle();
78 | }
79 |
80 | #endregion
81 | }
82 | }
--------------------------------------------------------------------------------
/Docs/ToDo_Ideas.txt:
--------------------------------------------------------------------------------
1 | Application improvement ideas
2 | =============================
3 | - Custom context menu colors for text and background (use contextmenustrip...)
4 |
5 | - When user activates notifications, make sure Windows settings are also updated to display notifications for WeekNumber by Voltura AB application
6 | suppression is stored in registry as well as a SquirrelSQL DB, need to get the GUID Windows assigns to the app, this could be used by querying the
7 | %LOCALAPPDATA%\Microsoft\Windows\Notifications\wpndatabase.db tables
8 | 1) Notification (query right after first app start and use HandlerId from row with Payload containing "WeekNumber by Voltura AB")
9 | 2) NotificationHandler, use key ID (HandlerID from 1), take Primary Id: Microsoft.Explorer.Notification.{GUID for registry use here}
10 | 3) Using PrimaryID .> save to settings
11 | 4) Remove suppression in registry when user activates messages in menu (or if show notifications setting is set during startup of app )
12 | Reg path:
13 | Computer\HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify\ToastAppIdentities\Microsoft.Explorer.Notification.{}
14 | Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.Explorer.Notification.{}
15 | Enabled dword 0 <- remove
16 |
--------------------------------------------------------------------------------
/Forms/DateForm.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Drawing;
5 | using System.Windows.Forms;
6 |
7 | #endregion
8 |
9 | namespace WeekNumber.Forms
10 | {
11 | ///
12 | /// Message form
13 | ///
14 | public partial class DateForm : Form
15 | {
16 | #region Private variables
17 |
18 | private Image _img;
19 | private bool _initComplete = false;
20 |
21 | #endregion Private variables
22 |
23 | #region Protected property
24 |
25 | ///
26 | /// Mouse location offset used form form movement
27 | ///
28 | protected Point Offset { get; set; }
29 |
30 | #endregion
31 |
32 | #region Private constructor
33 |
34 | private DateForm()
35 | {
36 | InitializeComponent();
37 | StartPosition = FormStartPosition.CenterScreen;
38 | SetControlTexts();
39 | }
40 |
41 | #endregion
42 |
43 | #region Public static method
44 |
45 | ///
46 | /// Displays Date form
47 | ///
48 | public static void Display()
49 | {
50 | using (DateForm dateForm = new DateForm())
51 | {
52 | dateForm.ShowDialog();
53 | }
54 | }
55 |
56 | #endregion
57 |
58 | #region Events handling
59 |
60 | private void Close_Click(object sender, EventArgs e)
61 | {
62 | DisposeImage();
63 | Close();
64 | }
65 |
66 | private void DisposeImage()
67 | {
68 | _img?.Dispose();
69 | _img = pictureBoxWeek.Image;
70 | _img?.Dispose();
71 | }
72 |
73 | private void SettingsTitle_MouseDown(object sender, MouseEventArgs e)
74 | {
75 | UpdateOffset(e);
76 | }
77 |
78 | private void SettingsTitle_MouseMove(object sender, MouseEventArgs e)
79 | {
80 | MoveForm(e);
81 | }
82 |
83 | private void MinimizePanel_MouseEnter(object sender, EventArgs e)
84 | {
85 | FocusMinimizeIcon();
86 | }
87 |
88 | private void MinimizePanel_MouseLeave(object sender, EventArgs e)
89 | {
90 | UnfocusMinimizeIcon();
91 | }
92 |
93 | private void MinimizePanel_Click(object sender, EventArgs e)
94 | {
95 | DisposeImage();
96 | Close();
97 | }
98 |
99 | private void MinimizePanelFrame_Click(object sender, EventArgs e)
100 | {
101 | DisposeImage();
102 | Close();
103 | }
104 |
105 | private void SelectedYearChanged(object sender, EventArgs e)
106 | {
107 | UpdateDaysDropdown();
108 | UpdateWeekInfo();
109 | }
110 |
111 | private void SelectedMonthChanged(object sender, EventArgs e)
112 | {
113 | UpdateDaysDropdown();
114 | UpdateWeekInfo();
115 | }
116 |
117 | private void SelectedDayChanged(object sender, EventArgs e)
118 | {
119 | UpdateWeekInfo();
120 | }
121 |
122 | private void DateForm_Shown(object sender, EventArgs e)
123 | {
124 | _initComplete = true;
125 | }
126 |
127 | #endregion
128 |
129 | #region Private methods
130 |
131 | private void UpdateWeekInfo(bool initial = false)
132 | {
133 | if (!_initComplete && !initial) return;
134 | string weekDayPrefix = string.Empty;
135 | if (int.TryParse(ccbYear.SelectedItem?.ToString(), out int year) == true &&
136 | int.TryParse(ccbMonth.SelectedItem?.ToString(), out int month) == true &&
137 | int.TryParse(ccbDay.SelectedItem?.ToString(), out int day) == true)
138 | {
139 | DateTime selectedDate = new DateTime(year, month, day);
140 | if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name == Resources.Swedish)
141 | {
142 | weekDayPrefix = Message.SWEDISH_DAY_OF_WEEK_PREFIX[(int)selectedDate.DayOfWeek];
143 | }
144 | int selectedWeek = Week.GetWeekNumber(selectedDate);
145 | lblInformation.Text = $"{Resources.Week} {selectedWeek}\r\n{weekDayPrefix}{selectedDate.ToLongDateString()}";
146 | _img = pictureBoxWeek.Image;
147 | pictureBoxWeek.Image = WeekIcon.GetImage(selectedWeek);
148 | _img?.Dispose();
149 | }
150 | else if (initial)
151 | {
152 | if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name == Resources.Swedish)
153 | {
154 | weekDayPrefix = Message.SWEDISH_DAY_OF_WEEK_PREFIX[(int)DateTime.Now.DayOfWeek];
155 | }
156 | lblInformation.Text = $"{Resources.Week} {Week.Current()}\r\n{weekDayPrefix}{DateTime.Now.ToLongDateString()}";
157 | pictureBoxWeek.Image = WeekIcon.GetImage(Week.Current());
158 | }
159 | else
160 | {
161 | lblInformation.Text = Resources.SelectDate;
162 | pictureBoxWeek.Image = null;
163 | }
164 | }
165 |
166 | private void UpdateDaysDropdown()
167 | {
168 |
169 | if (int.TryParse(ccbYear.SelectedItem?.ToString(), out int year) == true &&
170 | int.TryParse(ccbMonth.SelectedItem?.ToString(), out int month) == true)
171 | {
172 | bool gotPreviousSelectedDay = int.TryParse(ccbDay.SelectedItem?.ToString(), out int previousSelectedDay);
173 | if (ccbDay.Items.Count != DateTime.DaysInMonth(year, month))
174 | {
175 | ccbDay.Items.Clear();
176 | for (int i = 1; i <= DateTime.DaysInMonth(year, month); i++)
177 | {
178 | ccbDay.Items.Add(i.ToString());
179 | }
180 | if (gotPreviousSelectedDay == true && previousSelectedDay <= DateTime.DaysInMonth(year, month))
181 | {
182 | ccbDay.Text = previousSelectedDay.ToString();
183 | }
184 | else
185 | {
186 | ccbDay.Text = DateTime.Now.Day.ToString();
187 | }
188 | }
189 | }
190 | }
191 |
192 | private void SetControlTexts()
193 | {
194 | btnClose.Text = Resources.Close;
195 | lblDateFormTitle.Text = Message.CAPTION;
196 | Text = Message.CAPTION;
197 | lblYear.Text = Resources.Year;
198 | lblMonth.Text = Resources.Month;
199 | lblDay.Text = Resources.Day;
200 | PopulateYearDropdown();
201 | PopulateMonthDropdown();
202 | PopulateDayDropdown();
203 | UpdateWeekInfo(true);
204 | }
205 |
206 | private void PopulateDayDropdown()
207 | {
208 | ccbDay.Items.Clear();
209 | for (int i = 1; i <= DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month); i++)
210 | {
211 | ccbDay.Items.Add(i.ToString());
212 | }
213 | ccbDay.Text = DateTime.Now.Day.ToString();
214 | }
215 |
216 | private void PopulateMonthDropdown()
217 | {
218 | ccbMonth.Items.Clear();
219 | for (int i = 1; i < 13; i++)
220 | {
221 | ccbMonth.Items.Add(i.ToString());
222 | }
223 | ccbMonth.Text = DateTime.Now.Month.ToString();
224 | }
225 |
226 | private void PopulateYearDropdown()
227 | {
228 | ccbYear.Items.Clear();
229 | for (int i = DateTime.Now.Year - 10; i < DateTime.Now.Year + 10; i++)
230 | {
231 | ccbYear.Items.Add(i.ToString());
232 | }
233 | ccbYear.Text = DateTime.Now.Year.ToString();
234 | }
235 |
236 | private void FocusMinimizeIcon()
237 | {
238 | minimizePanel.BackColor = Color.LightGray;
239 | }
240 |
241 | private void MoveForm(MouseEventArgs e)
242 | {
243 | if (e.Button != MouseButtons.Left)
244 | {
245 | return;
246 | }
247 |
248 | Top = Cursor.Position.Y - Offset.Y;
249 | Left = Cursor.Position.X - Offset.X;
250 | }
251 |
252 | private void UpdateOffset(MouseEventArgs e)
253 | {
254 | Offset = new Point(e.X, e.Y);
255 | }
256 |
257 | private void UnfocusMinimizeIcon()
258 | {
259 | minimizePanel.BackColor = Color.White;
260 | }
261 |
262 | #endregion
263 | }
264 | }
--------------------------------------------------------------------------------
/Forms/DateForm.designer.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Forms;
3 |
4 | namespace WeekNumber.Forms
5 | {
6 | partial class DateForm
7 | {
8 | ///
9 | /// Required designer variable.
10 | ///
11 | private IContainer components = null;
12 |
13 | ///
14 | /// Clean up any resources being used.
15 | ///
16 | /// true if managed resources should be disposed; otherwise, false.
17 | protected override void Dispose(bool disposing)
18 | {
19 | if (disposing && (components != null))
20 | {
21 | components.Dispose();
22 | }
23 | base.Dispose(disposing);
24 | }
25 |
26 | #region Windows Form Designer generated code
27 |
28 | ///
29 | /// Required method for Designer support - do not modify
30 | /// the contents of this method with the code editor.
31 | ///
32 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Forms.Control.set_Text(System.String)")]
33 | private void InitializeComponent()
34 | {
35 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DateForm));
36 | this.lblDateFormTitle = new System.Windows.Forms.Label();
37 | this.minimizePanelFrame = new System.Windows.Forms.Panel();
38 | this.minimizePanel = new System.Windows.Forms.Panel();
39 | this.titleIcon = new System.Windows.Forms.PictureBox();
40 | this.btnClose = new System.Windows.Forms.Button();
41 | this.settingsPanel = new System.Windows.Forms.Panel();
42 | this.lblDay = new System.Windows.Forms.Label();
43 | this.lblMonth = new System.Windows.Forms.Label();
44 | this.lblYear = new System.Windows.Forms.Label();
45 | this.pictureBoxWeek = new System.Windows.Forms.PictureBox();
46 | this.lblInformation = new System.Windows.Forms.Label();
47 | this.ccbDay = new WeekNumber.Controls.CustomComboBox();
48 | this.ccbMonth = new WeekNumber.Controls.CustomComboBox();
49 | this.ccbYear = new WeekNumber.Controls.CustomComboBox();
50 | this.minimizePanelFrame.SuspendLayout();
51 | ((System.ComponentModel.ISupportInitialize)(this.titleIcon)).BeginInit();
52 | this.settingsPanel.SuspendLayout();
53 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxWeek)).BeginInit();
54 | this.SuspendLayout();
55 | //
56 | // lblDateFormTitle
57 | //
58 | this.lblDateFormTitle.Dock = System.Windows.Forms.DockStyle.Top;
59 | this.lblDateFormTitle.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
60 | this.lblDateFormTitle.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
61 | this.lblDateFormTitle.Location = new System.Drawing.Point(0, 0);
62 | this.lblDateFormTitle.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
63 | this.lblDateFormTitle.Name = "lblDateFormTitle";
64 | this.lblDateFormTitle.Padding = new System.Windows.Forms.Padding(56, 0, 0, 0);
65 | this.lblDateFormTitle.Size = new System.Drawing.Size(959, 58);
66 | this.lblDateFormTitle.TabIndex = 1;
67 | this.lblDateFormTitle.Text = "Select date to display its week number";
68 | this.lblDateFormTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
69 | this.lblDateFormTitle.MouseDown += new System.Windows.Forms.MouseEventHandler(this.SettingsTitle_MouseDown);
70 | this.lblDateFormTitle.MouseMove += new System.Windows.Forms.MouseEventHandler(this.SettingsTitle_MouseMove);
71 | //
72 | // minimizePanelFrame
73 | //
74 | this.minimizePanelFrame.Controls.Add(this.minimizePanel);
75 | this.minimizePanelFrame.Location = new System.Drawing.Point(892, 0);
76 | this.minimizePanelFrame.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
77 | this.minimizePanelFrame.Name = "minimizePanelFrame";
78 | this.minimizePanelFrame.Size = new System.Drawing.Size(63, 58);
79 | this.minimizePanelFrame.TabIndex = 3;
80 | this.minimizePanelFrame.Click += new System.EventHandler(this.MinimizePanelFrame_Click);
81 | this.minimizePanelFrame.MouseEnter += new System.EventHandler(this.MinimizePanel_MouseEnter);
82 | this.minimizePanelFrame.MouseLeave += new System.EventHandler(this.MinimizePanel_MouseLeave);
83 | //
84 | // minimizePanel
85 | //
86 | this.minimizePanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
87 | this.minimizePanel.BackColor = System.Drawing.Color.White;
88 | this.minimizePanel.Location = new System.Drawing.Point(12, 13);
89 | this.minimizePanel.Margin = new System.Windows.Forms.Padding(0);
90 | this.minimizePanel.Name = "minimizePanel";
91 | this.minimizePanel.Size = new System.Drawing.Size(44, 14);
92 | this.minimizePanel.TabIndex = 3;
93 | this.minimizePanel.Click += new System.EventHandler(this.MinimizePanel_Click);
94 | this.minimizePanel.MouseEnter += new System.EventHandler(this.MinimizePanel_MouseEnter);
95 | //
96 | // titleIcon
97 | //
98 | this.titleIcon.BackColor = System.Drawing.Color.Transparent;
99 | this.titleIcon.Image = ((System.Drawing.Image)(resources.GetObject("titleIcon.Image")));
100 | this.titleIcon.Location = new System.Drawing.Point(7, 7);
101 | this.titleIcon.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
102 | this.titleIcon.Name = "titleIcon";
103 | this.titleIcon.Size = new System.Drawing.Size(46, 47);
104 | this.titleIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
105 | this.titleIcon.TabIndex = 4;
106 | this.titleIcon.TabStop = false;
107 | //
108 | // btnClose
109 | //
110 | this.btnClose.BackColor = System.Drawing.Color.DeepSkyBlue;
111 | this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.DeepSkyBlue;
112 | this.btnClose.FlatAppearance.MouseDownBackColor = System.Drawing.Color.DeepSkyBlue;
113 | this.btnClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightBlue;
114 | this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
115 | this.btnClose.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
116 | this.btnClose.Location = new System.Drawing.Point(682, 337);
117 | this.btnClose.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
118 | this.btnClose.Name = "btnClose";
119 | this.btnClose.Size = new System.Drawing.Size(256, 72);
120 | this.btnClose.TabIndex = 1;
121 | this.btnClose.Text = "&Close";
122 | this.btnClose.UseVisualStyleBackColor = false;
123 | this.btnClose.Click += new System.EventHandler(this.Close_Click);
124 | //
125 | // settingsPanel
126 | //
127 | this.settingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
128 | | System.Windows.Forms.AnchorStyles.Right)));
129 | this.settingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
130 | this.settingsPanel.Controls.Add(this.lblDay);
131 | this.settingsPanel.Controls.Add(this.lblMonth);
132 | this.settingsPanel.Controls.Add(this.lblYear);
133 | this.settingsPanel.Controls.Add(this.pictureBoxWeek);
134 | this.settingsPanel.Controls.Add(this.lblInformation);
135 | this.settingsPanel.Controls.Add(this.ccbDay);
136 | this.settingsPanel.Controls.Add(this.ccbMonth);
137 | this.settingsPanel.Controls.Add(this.ccbYear);
138 | this.settingsPanel.Controls.Add(this.btnClose);
139 | this.settingsPanel.Location = new System.Drawing.Point(0, 58);
140 | this.settingsPanel.Margin = new System.Windows.Forms.Padding(0);
141 | this.settingsPanel.Name = "settingsPanel";
142 | this.settingsPanel.Size = new System.Drawing.Size(959, 430);
143 | this.settingsPanel.TabIndex = 2;
144 | //
145 | // lblDay
146 | //
147 | this.lblDay.AutoSize = true;
148 | this.lblDay.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
149 | this.lblDay.Location = new System.Drawing.Point(436, 33);
150 | this.lblDay.Name = "lblDay";
151 | this.lblDay.Size = new System.Drawing.Size(72, 41);
152 | this.lblDay.TabIndex = 20;
153 | this.lblDay.Text = "Day";
154 | //
155 | // lblMonth
156 | //
157 | this.lblMonth.AutoSize = true;
158 | this.lblMonth.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
159 | this.lblMonth.Location = new System.Drawing.Point(236, 33);
160 | this.lblMonth.Name = "lblMonth";
161 | this.lblMonth.Size = new System.Drawing.Size(113, 41);
162 | this.lblMonth.TabIndex = 19;
163 | this.lblMonth.Text = "Month";
164 | //
165 | // lblYear
166 | //
167 | this.lblYear.AutoSize = true;
168 | this.lblYear.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
169 | this.lblYear.Location = new System.Drawing.Point(36, 33);
170 | this.lblYear.Name = "lblYear";
171 | this.lblYear.Size = new System.Drawing.Size(77, 41);
172 | this.lblYear.TabIndex = 18;
173 | this.lblYear.Text = "Year";
174 | //
175 | // pictureBoxWeek
176 | //
177 | this.pictureBoxWeek.Location = new System.Drawing.Point(682, 43);
178 | this.pictureBoxWeek.Name = "pictureBoxWeek";
179 | this.pictureBoxWeek.Size = new System.Drawing.Size(256, 256);
180 | this.pictureBoxWeek.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
181 | this.pictureBoxWeek.TabIndex = 17;
182 | this.pictureBoxWeek.TabStop = false;
183 | //
184 | // lblInformation
185 | //
186 | this.lblInformation.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
187 | this.lblInformation.Location = new System.Drawing.Point(36, 162);
188 | this.lblInformation.Name = "lblInformation";
189 | this.lblInformation.Size = new System.Drawing.Size(581, 107);
190 | this.lblInformation.TabIndex = 16;
191 | this.lblInformation.Text = "Week 22\r\nSunday, 5th of June 2021";
192 | //
193 | // ccbDay
194 | //
195 | this.ccbDay.DropDownWidth = 174;
196 | this.ccbDay.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
197 | this.ccbDay.FormattingEnabled = true;
198 | this.ccbDay.HighlightColor = System.Drawing.Color.DeepSkyBlue;
199 | this.ccbDay.Location = new System.Drawing.Point(443, 87);
200 | this.ccbDay.Name = "ccbDay";
201 | this.ccbDay.Size = new System.Drawing.Size(174, 48);
202 | this.ccbDay.TabIndex = 15;
203 | this.ccbDay.SelectedIndexChanged += new System.EventHandler(this.SelectedDayChanged);
204 | //
205 | // ccbMonth
206 | //
207 | this.ccbMonth.DropDownWidth = 174;
208 | this.ccbMonth.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
209 | this.ccbMonth.FormattingEnabled = true;
210 | this.ccbMonth.HighlightColor = System.Drawing.Color.DeepSkyBlue;
211 | this.ccbMonth.Location = new System.Drawing.Point(243, 87);
212 | this.ccbMonth.Name = "ccbMonth";
213 | this.ccbMonth.Size = new System.Drawing.Size(174, 48);
214 | this.ccbMonth.TabIndex = 14;
215 | this.ccbMonth.SelectedIndexChanged += new System.EventHandler(this.SelectedMonthChanged);
216 | //
217 | // ccbYear
218 | //
219 | this.ccbYear.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
220 | this.ccbYear.FormattingEnabled = true;
221 | this.ccbYear.HighlightColor = System.Drawing.Color.DeepSkyBlue;
222 | this.ccbYear.Location = new System.Drawing.Point(43, 87);
223 | this.ccbYear.Name = "ccbYear";
224 | this.ccbYear.Size = new System.Drawing.Size(174, 48);
225 | this.ccbYear.TabIndex = 13;
226 | this.ccbYear.SelectedIndexChanged += new System.EventHandler(this.SelectedYearChanged);
227 | //
228 | // DateForm
229 | //
230 | this.AutoScaleDimensions = new System.Drawing.SizeF(14F, 29F);
231 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
232 | this.BackColor = System.Drawing.Color.DeepSkyBlue;
233 | this.ClientSize = new System.Drawing.Size(959, 488);
234 | this.ControlBox = false;
235 | this.Controls.Add(this.titleIcon);
236 | this.Controls.Add(this.minimizePanelFrame);
237 | this.Controls.Add(this.settingsPanel);
238 | this.Controls.Add(this.lblDateFormTitle);
239 | this.DoubleBuffered = true;
240 | this.ForeColor = System.Drawing.Color.White;
241 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
242 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
243 | this.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
244 | this.MaximizeBox = false;
245 | this.MinimizeBox = false;
246 | this.Name = "DateForm";
247 | this.ShowInTaskbar = false;
248 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
249 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
250 | this.TopMost = true;
251 | this.Shown += new System.EventHandler(this.DateForm_Shown);
252 | this.minimizePanelFrame.ResumeLayout(false);
253 | ((System.ComponentModel.ISupportInitialize)(this.titleIcon)).EndInit();
254 | this.settingsPanel.ResumeLayout(false);
255 | this.settingsPanel.PerformLayout();
256 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxWeek)).EndInit();
257 | this.ResumeLayout(false);
258 |
259 | }
260 |
261 | #endregion
262 |
263 | private Label lblDateFormTitle;
264 | private Panel minimizePanelFrame;
265 | private Panel minimizePanel;
266 | private PictureBox titleIcon;
267 | private Button btnClose;
268 | private Panel settingsPanel;
269 | private PictureBox pictureBoxWeek;
270 | private Label lblInformation;
271 | private Controls.CustomComboBox ccbDay;
272 | private Controls.CustomComboBox ccbMonth;
273 | private Controls.CustomComboBox ccbYear;
274 | private Label lblMonth;
275 | private Label lblYear;
276 | private Label lblDay;
277 | }
278 | }
--------------------------------------------------------------------------------
/Forms/MessageForm.Designer.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Forms;
3 |
4 | namespace WeekNumber.Forms
5 | {
6 | partial class MessageForm
7 | {
8 | ///
9 | /// Required designer variable.
10 | ///
11 | private IContainer components = null;
12 |
13 | ///
14 | /// Clean up any resources being used.
15 | ///
16 | /// true if managed resources should be disposed; otherwise, false.
17 | protected override void Dispose(bool disposing)
18 | {
19 | if (disposing && (components != null))
20 | {
21 | components.Dispose();
22 | }
23 | base.Dispose(disposing);
24 | }
25 |
26 | #region Windows Form Designer generated code
27 |
28 | ///
29 | /// Required method for Designer support - do not modify
30 | /// the contents of this method with the code editor.
31 | ///
32 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Forms.Control.set_Text(System.String)")]
33 | private void InitializeComponent()
34 | {
35 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MessageForm));
36 | this.lblMessageFormTitle = new System.Windows.Forms.Label();
37 | this.minimizePanelFrame = new System.Windows.Forms.Panel();
38 | this.minimizePanel = new System.Windows.Forms.Panel();
39 | this.titleIcon = new System.Windows.Forms.PictureBox();
40 | this.btnOK = new System.Windows.Forms.Button();
41 | this.settingsPanel = new System.Windows.Forms.Panel();
42 | this.messageBox = new System.Windows.Forms.TextBox();
43 | this.Link = new System.Windows.Forms.LinkLabel();
44 | this.minimizePanelFrame.SuspendLayout();
45 | ((System.ComponentModel.ISupportInitialize)(this.titleIcon)).BeginInit();
46 | this.settingsPanel.SuspendLayout();
47 | this.SuspendLayout();
48 | //
49 | // lblMessageFormTitle
50 | //
51 | this.lblMessageFormTitle.Dock = System.Windows.Forms.DockStyle.Top;
52 | this.lblMessageFormTitle.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
53 | this.lblMessageFormTitle.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
54 | this.lblMessageFormTitle.Location = new System.Drawing.Point(0, 0);
55 | this.lblMessageFormTitle.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
56 | this.lblMessageFormTitle.Name = "lblMessageFormTitle";
57 | this.lblMessageFormTitle.Padding = new System.Windows.Forms.Padding(56, 0, 0, 0);
58 | this.lblMessageFormTitle.Size = new System.Drawing.Size(959, 58);
59 | this.lblMessageFormTitle.TabIndex = 1;
60 | this.lblMessageFormTitle.Text = "Information";
61 | this.lblMessageFormTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
62 | this.lblMessageFormTitle.MouseDown += new System.Windows.Forms.MouseEventHandler(this.SettingsTitle_MouseDown);
63 | this.lblMessageFormTitle.MouseMove += new System.Windows.Forms.MouseEventHandler(this.SettingsTitle_MouseMove);
64 | //
65 | // minimizePanelFrame
66 | //
67 | this.minimizePanelFrame.Controls.Add(this.minimizePanel);
68 | this.minimizePanelFrame.Location = new System.Drawing.Point(892, 0);
69 | this.minimizePanelFrame.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
70 | this.minimizePanelFrame.Name = "minimizePanelFrame";
71 | this.minimizePanelFrame.Size = new System.Drawing.Size(63, 58);
72 | this.minimizePanelFrame.TabIndex = 3;
73 | this.minimizePanelFrame.Click += new System.EventHandler(this.MinimizePanelFrame_Click);
74 | this.minimizePanelFrame.MouseEnter += new System.EventHandler(this.MinimizePanel_MouseEnter);
75 | this.minimizePanelFrame.MouseLeave += new System.EventHandler(this.MinimizePanel_MouseLeave);
76 | //
77 | // minimizePanel
78 | //
79 | this.minimizePanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
80 | this.minimizePanel.BackColor = System.Drawing.Color.White;
81 | this.minimizePanel.Location = new System.Drawing.Point(12, 13);
82 | this.minimizePanel.Margin = new System.Windows.Forms.Padding(0);
83 | this.minimizePanel.Name = "minimizePanel";
84 | this.minimizePanel.Size = new System.Drawing.Size(44, 14);
85 | this.minimizePanel.TabIndex = 3;
86 | this.minimizePanel.Click += new System.EventHandler(this.MinimizePanel_Click);
87 | this.minimizePanel.MouseEnter += new System.EventHandler(this.MinimizePanel_MouseEnter);
88 | //
89 | // titleIcon
90 | //
91 | this.titleIcon.BackColor = System.Drawing.Color.Transparent;
92 | this.titleIcon.Image = ((System.Drawing.Image)(resources.GetObject("titleIcon.Image")));
93 | this.titleIcon.Location = new System.Drawing.Point(7, 7);
94 | this.titleIcon.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
95 | this.titleIcon.Name = "titleIcon";
96 | this.titleIcon.Size = new System.Drawing.Size(46, 47);
97 | this.titleIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
98 | this.titleIcon.TabIndex = 4;
99 | this.titleIcon.TabStop = false;
100 | //
101 | // btnOK
102 | //
103 | this.btnOK.BackColor = System.Drawing.Color.DeepSkyBlue;
104 | this.btnOK.FlatAppearance.BorderColor = System.Drawing.Color.DeepSkyBlue;
105 | this.btnOK.FlatAppearance.MouseDownBackColor = System.Drawing.Color.DeepSkyBlue;
106 | this.btnOK.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightBlue;
107 | this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
108 | this.btnOK.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
109 | this.btnOK.Location = new System.Drawing.Point(682, 332);
110 | this.btnOK.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
111 | this.btnOK.Name = "btnOK";
112 | this.btnOK.Size = new System.Drawing.Size(256, 72);
113 | this.btnOK.TabIndex = 1;
114 | this.btnOK.Text = "OK";
115 | this.btnOK.UseVisualStyleBackColor = false;
116 | this.btnOK.Click += new System.EventHandler(this.OK_Click);
117 | //
118 | // settingsPanel
119 | //
120 | this.settingsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
121 | | System.Windows.Forms.AnchorStyles.Right)));
122 | this.settingsPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
123 | this.settingsPanel.Controls.Add(this.messageBox);
124 | this.settingsPanel.Controls.Add(this.Link);
125 | this.settingsPanel.Controls.Add(this.btnOK);
126 | this.settingsPanel.Location = new System.Drawing.Point(0, 58);
127 | this.settingsPanel.Margin = new System.Windows.Forms.Padding(0);
128 | this.settingsPanel.Name = "settingsPanel";
129 | this.settingsPanel.Size = new System.Drawing.Size(959, 430);
130 | this.settingsPanel.TabIndex = 2;
131 | //
132 | // messageBox
133 | //
134 | this.messageBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(76)))), ((int)(((byte)(76)))));
135 | this.messageBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
136 | this.messageBox.Font = new System.Drawing.Font("Segoe UI Semibold", 10.2F, System.Drawing.FontStyle.Bold);
137 | this.messageBox.ForeColor = System.Drawing.Color.White;
138 | this.messageBox.Location = new System.Drawing.Point(12, 18);
139 | this.messageBox.Multiline = true;
140 | this.messageBox.Name = "messageBox";
141 | this.messageBox.ReadOnly = true;
142 | this.messageBox.RightToLeft = System.Windows.Forms.RightToLeft.No;
143 | this.messageBox.Size = new System.Drawing.Size(936, 234);
144 | this.messageBox.TabIndex = 12;
145 | this.messageBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
146 | //
147 | // Link
148 | //
149 | this.Link.ActiveLinkColor = System.Drawing.Color.LightSkyBlue;
150 | this.Link.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
151 | | System.Windows.Forms.AnchorStyles.Right)));
152 | this.Link.Font = new System.Drawing.Font("Segoe UI Semibold", 10.2F, System.Drawing.FontStyle.Bold);
153 | this.Link.LinkColor = System.Drawing.Color.DeepSkyBlue;
154 | this.Link.Location = new System.Drawing.Point(21, 265);
155 | this.Link.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
156 | this.Link.Name = "Link";
157 | this.Link.Size = new System.Drawing.Size(917, 42);
158 | this.Link.TabIndex = 11;
159 | this.Link.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
160 | this.Link.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.Link_LinkClicked);
161 | //
162 | // MessageForm
163 | //
164 | this.AutoScaleDimensions = new System.Drawing.SizeF(14F, 29F);
165 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
166 | this.BackColor = System.Drawing.Color.DeepSkyBlue;
167 | this.ClientSize = new System.Drawing.Size(959, 488);
168 | this.ControlBox = false;
169 | this.Controls.Add(this.titleIcon);
170 | this.Controls.Add(this.minimizePanelFrame);
171 | this.Controls.Add(this.settingsPanel);
172 | this.Controls.Add(this.lblMessageFormTitle);
173 | this.DoubleBuffered = true;
174 | this.ForeColor = System.Drawing.Color.White;
175 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
176 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
177 | this.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
178 | this.MaximizeBox = false;
179 | this.MinimizeBox = false;
180 | this.Name = "MessageForm";
181 | this.ShowInTaskbar = false;
182 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
183 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
184 | this.TopMost = true;
185 | this.minimizePanelFrame.ResumeLayout(false);
186 | ((System.ComponentModel.ISupportInitialize)(this.titleIcon)).EndInit();
187 | this.settingsPanel.ResumeLayout(false);
188 | this.settingsPanel.PerformLayout();
189 | this.ResumeLayout(false);
190 |
191 | }
192 |
193 | #endregion
194 | private Label lblMessageFormTitle;
195 | private Panel minimizePanelFrame;
196 | private Panel minimizePanel;
197 | private PictureBox titleIcon;
198 | private Button btnOK;
199 | private Panel settingsPanel;
200 | private LinkLabel Link;
201 | private TextBox messageBox;
202 | }
203 | }
--------------------------------------------------------------------------------
/Forms/MessageForm.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Diagnostics;
5 | using System.Drawing;
6 | using System.Windows.Forms;
7 |
8 | #endregion
9 |
10 | namespace WeekNumber.Forms
11 | {
12 | ///
13 | /// Message form
14 | ///
15 | public partial class MessageForm : Form
16 | {
17 | #region Public methods
18 |
19 | ///
20 | /// Set message to display in form
21 | ///
22 | /// Message text
23 | public void SetMessage(string messageText)
24 | {
25 | messageBox.Text = messageText;
26 | }
27 |
28 | ///
29 | /// Set link to product URL
30 | ///
31 | public void SetLink(string url)
32 | {
33 | Link.Text = url;
34 | }
35 |
36 | #endregion
37 |
38 | #region Protected class properties
39 |
40 | ///
41 | /// Mouse location offset used form form movement
42 | ///
43 | protected Point Offset { get; set; }
44 |
45 | #endregion
46 |
47 | #region Constructors
48 |
49 | ///
50 | /// Settings form constructor
51 | ///
52 | /// Message text
53 | public MessageForm(string messageText)
54 | {
55 | InitializeComponent();
56 | StartPosition = FormStartPosition.CenterScreen;
57 | SetControlTexts();
58 | SetMessage(messageText);
59 | }
60 |
61 | ///
62 | /// Settings form constructor
63 | ///
64 | public MessageForm()
65 | {
66 | InitializeComponent();
67 | StartPosition = FormStartPosition.CenterScreen;
68 | SetControlTexts();
69 | }
70 |
71 | #endregion
72 |
73 | #region Public static methods
74 |
75 | ///
76 | /// Display a message
77 | ///
78 | ///
79 | public static void DisplayMessage(string messageText)
80 | {
81 | using (MessageForm message = new MessageForm(messageText))
82 | {
83 | message.ShowDialog();
84 | }
85 | }
86 |
87 | ///
88 | /// Displays a message on dialogbox with matching icon
89 | ///
90 | ///
91 | ///
92 | public static void DisplayMessage(string messageText, bool error = false)
93 | {
94 | using (MessageForm message = new MessageForm(messageText))
95 | {
96 | if (error) message.titleIcon.Image = SystemIcons.Exclamation.ToBitmap();
97 | message.ShowDialog();
98 | }
99 | }
100 |
101 | ///
102 | /// Logs and displays message
103 | ///
104 | ///
105 | public static void LogAndDisplayMessage(string messageText)
106 | {
107 | Log.Info = messageText;
108 | using (MessageForm message = new MessageForm(messageText))
109 | {
110 | message.ShowDialog();
111 | }
112 | }
113 |
114 | ///
115 | /// Logs and displays message with Product URL link
116 | ///
117 | ///
118 | ///
119 | public static void LogAndDisplayLinkMessage(string messageText, string url)
120 | {
121 | Log.Info = messageText;
122 | using (MessageForm msgForm = new MessageForm(messageText))
123 | {
124 | msgForm.SetLink(url);
125 | msgForm.ShowDialog();
126 | }
127 | }
128 |
129 | #endregion
130 |
131 | #region Events handling
132 |
133 | private void OK_Click(object sender, EventArgs e)
134 | {
135 | Close();
136 | }
137 |
138 | private void SettingsTitle_MouseDown(object sender, MouseEventArgs e)
139 | {
140 | UpdateOffset(e);
141 | }
142 |
143 | private void SettingsTitle_MouseMove(object sender, MouseEventArgs e)
144 | {
145 | MoveForm(e);
146 | }
147 |
148 | private void MinimizePanel_MouseEnter(object sender, EventArgs e)
149 | {
150 | FocusMinimizeIcon();
151 | }
152 |
153 | private void MinimizePanel_MouseLeave(object sender, EventArgs e)
154 | {
155 | UnfocusMinimizeIcon();
156 | }
157 |
158 | private void MinimizePanel_Click(object sender, EventArgs e)
159 | {
160 | Close();
161 | }
162 |
163 | private void MinimizePanelFrame_Click(object sender, EventArgs e)
164 | {
165 | Close();
166 | }
167 |
168 | private void Link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
169 | {
170 | OpenUrl();
171 | Close();
172 | }
173 |
174 | #endregion
175 |
176 | #region Private methods
177 |
178 | private void SetControlTexts()
179 | {
180 | btnOK.Text = Resources.OK;
181 | lblMessageFormTitle.Text = Message.CAPTION;
182 | Text = Message.CAPTION;
183 | }
184 |
185 | private void FocusMinimizeIcon()
186 | {
187 | minimizePanel.BackColor = Color.LightGray;
188 | }
189 |
190 | private void MoveForm(MouseEventArgs e)
191 | {
192 | if (e.Button != MouseButtons.Left)
193 | {
194 | return;
195 | }
196 |
197 | Top = Cursor.Position.Y - Offset.Y;
198 | Left = Cursor.Position.X - Offset.X;
199 | }
200 |
201 | private void UpdateOffset(MouseEventArgs e)
202 | {
203 | Offset = new Point(e.X, e.Y);
204 | }
205 |
206 | private void UnfocusMinimizeIcon()
207 | {
208 | minimizePanel.BackColor = Color.White;
209 | }
210 |
211 | private void OpenUrl()
212 | {
213 | using (Process p = new Process())
214 | {
215 | p.StartInfo = new ProcessStartInfo
216 | {
217 | UseShellExecute = true,
218 | FileName = Link.Text
219 | };
220 | p.Start();
221 | }
222 | }
223 |
224 | #endregion
225 | }
226 | }
--------------------------------------------------------------------------------
/Forms/WeekNumberForDateForm.cs:
--------------------------------------------------------------------------------
1 | namespace WeekNumber.Forms
2 | {
3 | class WeekNumberForDateForm
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/IGui.cs:
--------------------------------------------------------------------------------
1 | namespace WeekNumber
2 | {
3 | ///
4 | /// GUI Interface
5 | ///
6 | public interface IGui
7 | {
8 | ///
9 | /// Updates icon on GUI with given week number
10 | ///
11 | /// The week number to display on icon
12 | /// The width and height of the icon
13 | /// Redraw context menu
14 | void UpdateIcon(int weekNumber, int iconResolution = (int)IconSize.Icon256, bool redrawContextMenu = false);
15 |
16 | ///
17 | /// Disposes GUI
18 | ///
19 | void Dispose();
20 |
21 | ///
22 | /// Event handler for when GUI (icon) update is requested
23 | ///
24 | event System.EventHandler UpdateRequest;
25 | }
26 | }
--------------------------------------------------------------------------------
/IconSize.cs:
--------------------------------------------------------------------------------
1 | namespace WeekNumber
2 | {
3 | #region Internal enum of icon sizes
4 |
5 | internal enum IconSize : int
6 | {
7 | Icon16 = 16,
8 | Icon20 = 20,
9 | Icon24 = 24,
10 | Icon32 = 32,
11 | Icon40 = 40,
12 | Icon48 = 48,
13 | Icon64 = 64,
14 | Icon128 = 128,
15 | Icon256 = 256,
16 | Icon512 = 512
17 | }
18 |
19 | #endregion
20 | }
21 |
--------------------------------------------------------------------------------
/Installation/License.de-DE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Installation/License.de-DE.txt
--------------------------------------------------------------------------------
/Installation/License.en-US.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Installation/License.en-US.txt
--------------------------------------------------------------------------------
/Installation/License.sv-SE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Installation/License.sv-SE.txt
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Voltura AB
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Log.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Diagnostics;
5 | using System.Globalization;
6 | using System.IO;
7 | using System.Windows.Forms;
8 |
9 | #endregion
10 | namespace WeekNumber
11 | {
12 | internal static class Log
13 | {
14 | #region Static variables
15 |
16 | private static readonly string logFile = Path.GetFileNameWithoutExtension(Application.ExecutablePath) + ".log";
17 | private static readonly string appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
18 | Application.CompanyName, Application.ProductName);
19 | private static readonly string logFileFullPath = Path.Combine(appDataFolder, logFile);
20 | private static readonly int DEFAULT_LOGFILE_SIZE_IN_MEGABYTES = 10;
21 |
22 | #endregion
23 |
24 | #region Internal static constructor
25 |
26 | ///
27 | /// Constructor - Init log
28 | ///
29 | static Log()
30 | {
31 | Init();
32 | }
33 |
34 | #endregion
35 |
36 | #region Internal methods
37 |
38 | ///
39 | /// Init log
40 | ///
41 | internal static void Init()
42 | {
43 | try
44 | {
45 | if (!Directory.Exists(appDataFolder))
46 | {
47 | Directory.CreateDirectory(appDataFolder);
48 | }
49 | Trace.Listeners.Clear();
50 | if (!Settings.SettingIsValue(Resources.UseApplicationLog, "True"))
51 | {
52 | Trace.Listeners.Clear();
53 | Trace.Flush();
54 | Trace.Close();
55 | if (File.Exists(logFileFullPath)) File.Delete(logFileFullPath);
56 | return;
57 | }
58 | FileStream fs = new FileStream(logFileFullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete, 1024, FileOptions.WriteThrough);
59 | TextWriterTraceListener traceListener = new TextWriterTraceListener(fs);
60 | Trace.Listeners.Add(traceListener);
61 | Trace.AutoFlush = true;
62 | Trace.UseGlobalLock = false;
63 | }
64 | catch (Exception ex)
65 | {
66 | Debug.WriteLine(ex);
67 | }
68 | }
69 |
70 | internal static void Close(string info)
71 | {
72 | Info = info;
73 | Close();
74 | }
75 |
76 | internal static void Close()
77 | {
78 | Truncate();
79 | Trace.Flush();
80 | Trace.Close();
81 | }
82 |
83 | ///
84 | /// Truncate log
85 | ///
86 | internal static void Truncate()
87 | {
88 | try
89 | {
90 | Trace.Flush();
91 | Trace.Close();
92 | Trace.Listeners.Clear();
93 | FileInfo fi = new FileInfo(logFileFullPath);
94 | if (fi.Exists)
95 | {
96 | int trimSize = Settings.GetIntSetting(Resources.MaxLogFileSizeInMB, DEFAULT_LOGFILE_SIZE_IN_MEGABYTES) * 1024 * 1024;
97 | if (fi.Length > trimSize)
98 | {
99 | using (MemoryStream ms = new MemoryStream(trimSize))
100 | using (FileStream s = new FileStream(logFileFullPath, FileMode.Open, FileAccess.ReadWrite))
101 | {
102 | s.Seek(-trimSize, SeekOrigin.End);
103 | byte[] bytes = new byte[trimSize];
104 | s.Read(bytes, 0, trimSize);
105 | ms.Write(bytes, 0, trimSize);
106 | ms.Position = 0;
107 | s.SetLength(trimSize);
108 | s.Position = 0;
109 | ms.CopyTo(s);
110 | }
111 | }
112 | }
113 | }
114 | catch (Exception ex)
115 | {
116 | Debug.WriteLine(ex);
117 | }
118 | Init();
119 | }
120 |
121 | internal static void Show(string info)
122 | {
123 | Info = info;
124 | Show();
125 | }
126 |
127 | internal static void Show()
128 | {
129 | try
130 | {
131 | if (File.Exists(logFileFullPath))
132 | {
133 | using (Process process = new Process() { StartInfo = new ProcessStartInfo(logFileFullPath) { UseShellExecute = true } })
134 | {
135 | process.Start();
136 | }
137 | }
138 | }
139 | catch (InvalidOperationException ex)
140 | {
141 | Error = ex;
142 | }
143 | }
144 |
145 | internal static void LogCaller()
146 | {
147 | StackTrace stackTrace = new StackTrace();
148 | string method = stackTrace.GetFrame(1).GetMethod().Name;
149 | string methodClass = stackTrace.GetFrame(1).GetMethod().DeclaringType.FullName;
150 | string calleeMethod = stackTrace.GetFrame(2).GetMethod().Name;
151 | string calleeClass = stackTrace.GetFrame(2).GetMethod().DeclaringType.FullName;
152 | string infoText = $"{methodClass}::{(method == ".ctor" ? "constructor" : method)} called from {calleeClass}::{(calleeMethod == ".ctor" ? "constructor" : calleeMethod)}";
153 | Info = infoText;
154 | }
155 |
156 | #endregion
157 |
158 | #region Internal static log properties
159 |
160 | ///
161 | /// Log info
162 | ///
163 | internal static string Info
164 | {
165 | private get => string.Empty;
166 | set
167 | {
168 | try
169 | {
170 | string formattedValue = value.Replace('\r', ' ').Replace('\n', ' ').Trim();
171 | Trace.TraceInformation($"{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff", CultureInfo.InvariantCulture)} {formattedValue}");
172 | }
173 | catch (Exception ex)
174 | {
175 | Debug.WriteLine(ex);
176 | }
177 | }
178 | }
179 |
180 | ///
181 | /// Log error
182 | ///
183 | internal static Exception Error
184 | {
185 | private get => new ArgumentNullException(logFile);
186 | set
187 | {
188 | try
189 | {
190 | string formattedValue = value.ToString().Replace('\r', ' ').Replace('\n', ' ').Trim();
191 | Trace.TraceError($"{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff", CultureInfo.InvariantCulture)} {formattedValue}");
192 | }
193 | catch (Exception ex)
194 | {
195 | Debug.WriteLine(ex);
196 | }
197 | }
198 | }
199 |
200 | ///
201 | /// Log an error string
202 | ///
203 | internal static string ErrorString
204 | {
205 | private get => string.Empty;
206 | set
207 | {
208 | try
209 | {
210 | string formattedValue = value.Replace('\r', ' ').Replace('\n', ' ').Trim();
211 | Trace.TraceError($"{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff", CultureInfo.InvariantCulture)} {formattedValue}");
212 | }
213 | catch (Exception ex)
214 | {
215 | Debug.WriteLine(ex);
216 | }
217 | }
218 | }
219 |
220 | #endregion
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/Message.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Windows.Forms;
5 |
6 | #endregion Using statements
7 |
8 | namespace WeekNumber
9 | {
10 | internal static class Message
11 | {
12 | #region Internal readonly strings
13 |
14 | internal static readonly string[] SWEDISH_DAY_OF_WEEK_PREFIX = { "Söndagen ", "Måndagen ", "Tisdagen ", "Onsdagen ", "Torsdagen ", "Fredagen ", "Lördagen " };
15 | internal static readonly string CAPTION = $"{Resources.ProductName} {Resources.Version} {Application.ProductVersion}";
16 |
17 | #endregion Internal readonly strings
18 |
19 | #region Show Information or Error dialog methods
20 |
21 | internal static void Show(string text, Exception ex = null)
22 | {
23 | var message = ex is null ? text : $"{text}\r\n{ex}";
24 | if (ex is null) Log.Info = message; else Log.ErrorString = message;
25 | Forms.MessageForm.DisplayMessage(message, !(ex is null));
26 | }
27 |
28 | internal static void Show(string text)
29 | {
30 | Show(text, null);
31 | }
32 |
33 | internal static void Show(string message, bool isError)
34 | {
35 | if (isError) Log.Info = message; else Log.ErrorString = message;
36 | Forms.MessageForm.DisplayMessage(message, isError);
37 | }
38 |
39 | internal static bool UserAcceptedQuestion(string message)
40 | {
41 | Log.Info = message;
42 | // TODO: Customize and use MessageForm
43 | DialogResult userAnswer = MessageBox.Show(message, CAPTION, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
44 | return userAnswer == DialogResult.Yes;
45 | }
46 |
47 | #endregion Show Information or Error dialog methods
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | #endregion Using statements
7 |
8 | namespace WeekNumber
9 | {
10 | internal static class NativeMethods
11 | {
12 | #region Internal constants
13 |
14 | internal const int HWND_BROADCAST = 0xffff;
15 | internal const int WM_SETTINGCHANGE = 0x001a;
16 |
17 | #endregion Internal constants
18 |
19 | #region External user32.dll function to free GDI+ icon from memory
20 |
21 | [DllImport("user32.dll", CharSet = CharSet.Auto)]
22 | [return: MarshalAs(UnmanagedType.Bool)]
23 | internal static extern bool DestroyIcon(IntPtr handle);
24 |
25 | #endregion External user32.dll function to free GDI+ icon from memory
26 |
27 | #region External user32.dll function to inform Windows about changed taskbar setting
28 |
29 | [DllImport("User32.dll", CharSet = CharSet.Auto)]
30 | [return: MarshalAs(UnmanagedType.Bool)]
31 | internal static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam);
32 |
33 | #endregion External user32.dll function to inform Windows about changed taskbar setting
34 |
35 | #region External wininet.dll function to check Internet connection state
36 |
37 | [DllImport("wininet.dll", CharSet = CharSet.Auto)]
38 | [return: MarshalAs(UnmanagedType.Bool)]
39 | private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
40 |
41 | internal static bool IsConnectedToInternet()
42 | {
43 | return InternetGetConnectedState(out _, 0);
44 | }
45 |
46 | #endregion External wininet.dll function to check Internet connection state
47 |
48 | #region Refresh tray area (only English user interface)
49 |
50 | [StructLayout(LayoutKind.Sequential)]
51 | public struct RECT
52 | {
53 | public int left;
54 | public int top;
55 | public int right;
56 | public int bottom;
57 | }
58 |
59 | [DllImport("user32.dll")]
60 | public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
61 |
62 | [DllImport("user32.dll")]
63 | public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
64 | string lpszWindow);
65 |
66 | [DllImport("user32.dll")]
67 | public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
68 |
69 | [DllImport("user32.dll")]
70 | public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
71 |
72 | public static void RefreshTrayArea()
73 | {
74 | Log.LogCaller();
75 | IntPtr systemTrayContainerHandle = FindWindow("Shell_TrayWnd", null);
76 | IntPtr systemTrayHandle = FindWindowEx(systemTrayContainerHandle, IntPtr.Zero, "TrayNotifyWnd", null);
77 | IntPtr sysPagerHandle = FindWindowEx(systemTrayHandle, IntPtr.Zero, "SysPager", null);
78 | IntPtr notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32", "Notification Area");
79 | if (notificationAreaHandle == IntPtr.Zero)
80 | {
81 | notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32",
82 | "User Promoted Notification Area");
83 | IntPtr notifyIconOverflowWindowHandle = FindWindow("NotifyIconOverflowWindow", null);
84 | IntPtr overflowNotificationAreaHandle = FindWindowEx(notifyIconOverflowWindowHandle, IntPtr.Zero,
85 | "ToolbarWindow32", "Overflow Notification Area");
86 | RefreshTrayArea(overflowNotificationAreaHandle);
87 | }
88 | RefreshTrayArea(notificationAreaHandle);
89 | }
90 |
91 | private static void RefreshTrayArea(IntPtr windowHandle)
92 | {
93 | const uint wmMousemove = 0x0200;
94 | GetClientRect(windowHandle, out RECT rect);
95 | for (var x = 0; x < rect.right; x += 5)
96 | for (var y = 0; y < rect.bottom; y += 5)
97 | SendMessage(windowHandle, wmMousemove, 0, (y << 16) + x);
98 | }
99 |
100 | #endregion Refresh tray area (only English user interface)
101 | }
102 | }
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Runtime;
5 | using System.Threading;
6 | using System.Windows.Forms;
7 | using System.Windows.Forms.VisualStyles;
8 |
9 | #endregion Using statements
10 |
11 | namespace WeekNumber
12 | {
13 | internal class Program
14 | {
15 | #region Private variable to allow only one instance of application
16 |
17 | private static readonly Mutex Mutex = new Mutex(true, "550adc75-8afb-4813-ac91-8c8c6cb681ae");
18 |
19 | #endregion Private variable to allow only one instance of application
20 |
21 | #region Application starting point
22 |
23 | [STAThread]
24 | private static void Main()
25 | {
26 | if (!Mutex.WaitOne(TimeSpan.Zero, true))
27 | {
28 | return;
29 | }
30 | WeekApplicationContext context = null;
31 | try
32 | {
33 | Settings.RestoreBackupSettings();
34 | Log.Init();
35 | Settings.SetCultureInfoFromSystemOrSettings();
36 | AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
37 | Log.Info = "=== Application started ===";
38 | Log.Info = Application.ProductName + " version " + Application.ProductVersion;
39 | NativeMethods.RefreshTrayArea();
40 | SetGCSettings();
41 | Application.EnableVisualStyles();
42 | Application.VisualStyleState = VisualStyleState.ClientAndNonClientAreasEnabled;
43 | Application.SetCompatibleTextRenderingDefault(false);
44 | context = new WeekApplicationContext();
45 | if (context?.Gui != null)
46 | {
47 | Application.Run(context);
48 | }
49 | }
50 | finally
51 | {
52 | Log.Close("=== Application ended ===");
53 | context?.Dispose();
54 | Mutex.ReleaseMutex();
55 | }
56 | }
57 |
58 | #endregion Application starting point
59 |
60 | #region Private methods
61 |
62 | ///
63 | /// Configures garbarge collection settings
64 | ///
65 | private static void SetGCSettings()
66 | {
67 | Log.LogCaller();
68 | GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
69 | GCSettings.LatencyMode = GCLatencyMode.Batch;
70 | }
71 |
72 | #endregion Private methods that configures garbarge collection settings
73 |
74 | #region Global unhandled Exception trap
75 |
76 | ///
77 | /// Catches all unhandled exceptions for the application
78 | /// Writes the exception to the application log file
79 | /// Terminates the application with exit code -1
80 | ///
81 | ///
82 | ///
83 | private static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
84 | {
85 | Exception ex = (Exception)e.ExceptionObject;
86 | Log.Error = ex;
87 | Message.Show(Resources.UnhandledException, ex);
88 | Log.Close("=== Application ended ===");
89 | Environment.Exit(1);
90 | }
91 |
92 | #endregion Global unhandled Exception trap
93 | }
94 | }
--------------------------------------------------------------------------------
/Properties/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System.Reflection;
4 | using System.Resources;
5 | using System.Runtime.InteropServices;
6 |
7 | #endregion Using statements
8 |
9 | #region Assembly information
10 |
11 | [assembly: AssemblyTitle("WeekNumber by Voltura AB")]
12 | [assembly: AssemblyDescription("WeekNumber by Voltura AB")]
13 | [assembly: AssemblyConfiguration("")]
14 | [assembly: AssemblyCompany("Voltura AB")]
15 | [assembly: AssemblyProduct("WeekNumber")]
16 | [assembly: AssemblyCopyright("Copyright © Voltura AB 2018-2024")]
17 | [assembly: AssemblyTrademark("")]
18 | [assembly: AssemblyCulture("")]
19 | [assembly: ComVisible(false)]
20 | [assembly: Guid("550adc75-8afb-4813-ac91-8c8c6cb681ae")]
21 | [assembly: AssemblyVersion("1.6.6.9")]
22 | [assembly: AssemblyFileVersion("1.6.6.9")]
23 | [assembly: NeutralResourcesLanguage("en-US")]
24 |
25 | #endregion Assembly information
--------------------------------------------------------------------------------
/Properties/WeekNumber.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Properties/WeekNumber.snk
--------------------------------------------------------------------------------
/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | True/PM
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/README.de-DE.md:
--------------------------------------------------------------------------------
1 | 🌍[English](README.md) ∙ [Deutsch](README.de-DE.md) ∙ [Svenska](README.sv-SE.md)
2 |
3 | # WeekNumber
4 | Windows 11/10 Systemtray-Anwendung, die die aktuelle Kalenderwoche anzeigt
5 |
6 |

7 |
8 | [](https://github.com/voltura/weeknumber/releases/latest/download/WeekNumber_v1.6.6.9.zip)
9 |
10 | []()
11 | []()
12 |
13 | ## Funktionen
14 | Das aktuelle Kalenderwoche wird als Symbol im Systemtray der Windows-Taskleiste angezeigt.
15 | Durch Doppelklicken auf das Symbol können Sie die Kalenderwoche für andere Daten nachschlagen.
16 |
17 | Stellen Sie ein, dass die Anwendung mit Windows startet, passen Sie die Symbolfarben, die Sprache, Benachrichtigungen, Kalenderregeln und vieles mehr an. Für eine detaillierte Beschreibung siehe den _**Hilfebereich**_ unten.
18 |
19 | ### Sprachunterstützung
20 | - Englisch
21 | - Deutsch
22 | - Schwedisch
23 |
24 | _Wenn Sie eine Übersetzung in eine andere Sprache beitragen möchten, erstellen Sie bitte ein Issue auf GitHub, und ich werde Sie kontaktieren!_
25 |
26 | ## Screenshots
27 | #### Symbol mit Standardfarben
28 | 
29 |
30 | #### Kontextmenü - Einstellungsmenü mit Sprachauswahl
31 | ![Kontextmenü]()
32 |
33 | #### Kalenderwoche für ein beliebiges Datum nachschlagen
34 | 
35 |
36 | #### Beispiele für Symbole mit benutzerdefinierten Farben
37 |   
38 |
39 | #### Farbauswahl, mit der Möglichkeit, benutzerdefinierte Farben zu definieren und zu verwenden; sowohl die Textfarbe als auch die Hintergrundfarbe des Symbols können geändert werden
40 | 
41 |
42 | ## Installation
43 | Zip-Datei herunterladen, extrahieren und WeekNumber.exe ausführen.
44 |
45 | Eine Benachrichtigung wird angezeigt, wenn WeekNumber gestartet ist
46 |
47 | 
48 |
49 | Das aktuelle Kalenderwoche wird nun unter den Systemtraysymbolen angezeigt. Wenn Sie die Kalenderwoche nicht sehen, klicken Sie auf das Dachsymbol (^) im Systemtray und ziehen Sie das Symbol herunter, damit es sichtbar wird.
50 |
51 |
52 | ## Hilfebereich
53 | Alle Funktionen sind durch Rechtsklick auf das Symbol der Anwendung im Windows-Systemtray zugänglich.
54 | Wenn Sie das Symbol der Anwendung nicht sehen, klicken Sie auf das Dachsymbol (^) im Systemtray, klicken und halten Sie die Maustaste gedrückt, während Sie das Symbol in den Systemtray ziehen; das Symbol wird dort fixiert und sichtbar.
55 |
56 | ### Kontextmenü:
57 | - **Über WeekNumber** - _Zeigt Versionsinformationen an_
58 | - **Einstellungen**
59 | - **Mit Windows starten** - _Wenn angekreuzt, startet die Anwendung automatisch mit Windows_
60 | - **Sprache** - _Ändert die Sprache, die die Anwendung verwendet_
61 | - **English** - _Englisch_
62 | - **Deutsch**
63 | - **Svenska**
64 | - **Anwendungsprotokoll**
65 | - **Anwendungsprotokoll verwenden** - _Wenn angekreuzt, schreibt die Anwendung in eine Protokolldatei_
66 | - **Anwendungsprotokoll anzeigen** - _Wenn oben angekreuzt, wird die Protokolldatei der Anwendung in einem Texteditor angezeigt (technisches Protokoll)_
67 | - **Benachrichtigungen**
68 | - **Startbenachrichtigung anzeigen** - _Wenn angekreuzt, zeigt die Anwendung eine Startbenachrichtigung an_
69 |
70 |
71 |
72 | - **Neue Wochenbenachrichtigung anzeigen** - _Wenn angekreuzt, wird eine Benachrichtigung angezeigt, wenn die aktuelle Woche sich ändert_
73 |
74 |
75 |
76 | - **Stille Benachrichtigungen verwenden** - _Wenn angekreuzt, wird kein Ton abgespielt, wenn diese Anwendung Benachrichtigungen anzeigt_
77 | - **Kleine/große Taskleistensymbole verwenden** - _Wechselt zwischen großen und kleinen Taskleistensymbolen. Haben Sie Schwierigkeiten, die Kalenderwoche zu sehen? Versuchen Sie, große Taskleistensymbole zu verwenden_
78 | - **Einstellungen exportieren..." - _Möglichkeit, eine Kopie der aktuellen Anwendungseinstellungen zu exportieren/speichern_
79 | - **Einstellungen importieren..." - _Möglichkeit, eine zuvor exportierte/gespeicherte Kopie der Anwendungseinstellungen zu importieren_
80 | - **Kalender** - _Kalenderregeln, die die Anwendung verwendet; normalerweise stammen diese aus den regionalen Einstellungen, die im System eingestellt sind, können aber hier manuell angepasst werden_
81 | - **'Erster-Tag-in-der-Woche'-Regel** - _Kalenderregel, wählen Sie den Tag, an dem eine Woche beginnt_
82 | - **'Erste-Woche-des-Jahres'-Regel** - _Eine weitere Kalenderregel, die angibt, welche Regel für die erste Woche des Jahres verwendet werden soll_
83 | - **Symbol** - _Einstellungen für das Anwendungssymbol_
84 | - **Symbolfarben** - _Möglichkeit, die Farben der Anwendung anzupassen_
85 | - **Symbolauflösung** - _Möglichkeit, die Auflösung des WeekNumber-Symbols anzupassen; wenn das Symbol verschwommen aussieht, kann eine andere Auflösung ein besseres Symbolbild liefern_
86 | - **Grafikeinstellungen** - _Möglichkeit, die Grafikoptionen anzupassen, die beim Zeichnen des Symbols durch die Anwendung verwendet werden_
87 | - **Glättungsmodus**
88 | - **Kompositionsqualität**
89 | - **Interpolationsmodus**
90 | - **Textkontrast**
91 | - **Symbol speichern...** - _Speichert das aktuelle WeekNumber-Symbol in einer .ico-Datei_
92 | - **Kalenderwoche für Datum erhalten...** - _Zeigt die Kalenderwoche für das angegebene Datum an_
93 |
94 |
95 | - **WeekNumber beenden** - _Beendet die Anwendung. Starten Sie sie erneut im Windows-Startmenü_
96 |
97 | ## Spenden
98 | *- WeekNumber ist vollständig kostenlos und Open Source. Spenden sind willkommen!*
99 |
100 | [](https://www.paypal.com/donate?hosted_button_id=7PN65YXN64DBG) __⟵__ _**Hier klicken, um zu spenden!**_
101 |
102 | [](https://ko-fi.com/G2G74W5F8) __⟵__ _**Hier klicken, um mir einen Kaffee zu kaufen!**_
103 |
104 | ## Statistik
105 | [](https://github.com/voltura/WeekNumber/issues)
106 | []()
107 | []()
108 |
109 | []()
110 | []()
111 | []()
112 | []()
113 | []()
114 | []()
115 | []()
116 | 
117 |
118 | 
119 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 🌍[English](README.md) ∙ [Deutsch](README.de-DE.md) ∙ [Svenska](README.sv-SE.md)
2 |
3 | # WeekNumber
4 | Windows 11/10 system tray area application that displays the current week number
5 |
6 |

7 |
8 |
9 | [](https://github.com/voltura/weeknumber/releases/latest/download/WeekNumber_v1.6.6.9.zip)
10 |
11 | []()
12 | []()
13 |
14 | ## Features
15 | Always see the current week number in the system tray area in Windows taskbar and lookup the week number for any other date via double-click on the application icon.
16 |
17 | Options to start with Windows, customize icon colors, language, notifications, calendar rules and more. For details see _**Help section**_ below.
18 |
19 | ### Supported Languages
20 | - English
21 | - Deutsch
22 | - Swedish
23 |
24 | _If you want to contribute with another language, please create an Issue on Github and I'll contact you!_
25 |
26 | ## Screenshots
27 | #### System tray area icon with default colors
28 | 
29 | #### Context menu - accessible via right-click on icon - with language selection
30 | 
31 | #### Find out week number for any date
32 | 
33 |
34 | #### System tray area icon with customized colors
35 |   
36 | #### Icon color picker, possible to define and use custom colors; both icon text and background can be customized
37 | 
38 |
39 | ## Installation
40 | After download of WeekNumber_v1.6.6.9.zip via [*Download latest release*](https://github.com/voltura/weeknumber/releases/latest/download/WeekNumber_v1.6.6.9.zip) first unzip the archive, then run WeekNumber.exe.
41 | To remove the application just delete the executable and other files extracted from the zip archive and the generated application configuration file WeekNumber.exe.config.
42 |
43 | ### Download notes
44 | Choose to keep the file downloaded if prompted - it will look similar to this (depends on your web browser and settings)
45 |
46 | 
47 |
48 |
49 | ### Security notes / alternative lightweight version
50 | Microsoft Defender / Windows Security could identify application as a virus, trojan and/or malware which is *not* the case.
51 | I have created a lightweight version that does not trigger any false alarm, this version only can display the current week number in the task area, nothing else.
52 | Not autostart with Windows (it can manually be made to start with Windows - google how).
53 | Nor do the lightweight version have options to change icon colors or anything else that the full version of WeekNumber can do.
54 |
55 | See more [here](https://voltura.github.io/WeekNumberLite2/) if interested.
56 |
57 | ## Help section
58 | All application features are accessible via right-click on the application icon residing in the system tray area in Windows taskbar.
59 | If the application icon is not visible then press the ^ symbol on the system tray area, click and hold on the application icon and then drag it to the visible system tray area to pin it there.
60 |
61 | ### Context menu options:
62 | - **About WeekNumber** - _Displays version information_
63 | - **Settings**
64 | - **Start with Windows** - _If ticked, the application starts automatically with Windows_
65 | - **Language** - _Change language used by the application_
66 | - **English**
67 | - **Deutsch**
68 | - **Svenska** - _Swedish_
69 | - **Application log**
70 | - **Use application log** - _Application writes to a log file if ticked_
71 | - **Show application log** - _If above is ticked, opens the application log file in a text editor; quite technical_
72 | - **Notifications** - _Control the application notification messages in sub-menus_
73 | - **Display startup notification** - _If ticked, the application will show a notification when started_
74 |
75 |
76 |
77 | - **Display new week notification** - _If ticked, a notification will be shown when the week changes_
78 |
79 |
80 |
81 | - **Use silent notifications** - _If ticked, any notifications for this application will not trigger system sounds to be played_
82 | - **Use small / large taskbar buttons** - _Toogles Windows taskbar size and also adjusts the application icon resolution to match. Having trouble seeing the week number? Try using large taskbar buttons_
83 | - **Export settings...** - _Option to export / backup the current application settings_
84 | - **Import settings...** - _Option to import previously exported / backed up application settings_
85 | - **Calendar** - _Calendar rules used by the application; per default the application uses the systems regional settings to figure this out, but it can be manually overridden here_
86 | - **First Day Of Week** - _Calendar rule, select what day a week starts on_
87 | - **Calendar week rule** - _Additional calendar rule that tells what rule is used for the first week of a year_
88 | - **Icon** - _Application icon settings_
89 | - **Icon colors** - _Allows user to change icon background and foreground color or reset colors used back to default in sub-menus_
90 | - **Icon resolution** - _Possibility to tweak the WeekNumber icon resolution, if the icon is fuzzy setting a higher or lower resolution can help with apperance_
91 | - **Graphics settings** - _Possibility to tweak icon graphics settings used by the application when drawing the week number icon_
92 | - **Smoothing mode**
93 | - **Compositing Quality**
94 | - **Interpolation Mode**
95 | - **Text Contrast**
96 | - **Save icon...** - _Saves the current WeekNumber icon displayed to a .ico file_
97 | - **Get week number for date...** - _Get week number for specified date_
98 |
99 |
100 | - **Exit WeekNumber** - _Closes the application. Start it again from the Windows Start Menu_
101 |
102 | ## Donations
103 | *- WeekNumber is completely free and open source. Donations are very much appreciated!*
104 |
105 | [](https://www.paypal.com/donate?hosted_button_id=7PN65YXN64DBG) __⟵__ _**Press here to donate!**_
106 |
107 | [](https://ko-fi.com/G2G74W5F8) __⟵__ _**Press here to buy me a coffee!**_
108 |
109 | ## Statistics
110 | [](https://github.com/voltura/WeekNumber/issues)
111 | []()
112 | []()
113 |
114 | []()
115 | []()
116 | []()
117 | []()
118 | []()
119 | []()
120 | []()
121 | 
122 |
123 | 
124 |
--------------------------------------------------------------------------------
/README.sv-SE.md:
--------------------------------------------------------------------------------
1 | 🌍[English](README.md) ∙ [Deutsch](README.de-DE.md) ∙ [Svenska](README.sv-SE.md)
2 |
3 | # WeekNumber
4 | Windows 11/10 systemfältsapplikation som visar aktuellt veckonummer
5 |
6 |

7 |
8 | [](https://github.com/voltura/weeknumber/releases/latest/download/WeekNumber_v1.6.6.9.zip)
9 |
10 | []()
11 | []()
12 |
13 | ## Funktioner
14 | Aktuellt veckonummer visas som en ikon i systemfältet i Windows aktivitetsfält.
15 | Slå upp veckonummer för andra datum genom att dubbel-klicka på ikonen.
16 |
17 | Ställ in att starta med Windows, anpassa ikonfärger, språk, notiser, kalender-regler och mycket mer. För detaljerad beskrivning se _**Hjälpavsnitt**_ nedan.
18 |
19 | ### Språkstöd
20 | - Engelska
21 | - Tyska
22 | - Svenska
23 |
24 | _Om du vill bidra med översättning till ett annat språk, vänligen skapa ett ärende på GitHub så kontaktar jag dig!_
25 |
26 | ## Skärmbilder
27 | #### Ikon med standard-färger
28 | 
29 |
30 | #### Högerklicks-meny - Inställningsmeny med språkval
31 | 
32 |
33 | #### Ta reda på veckonummer för valfritt datum
34 | 
35 |
36 | #### Exempel på ikoner med anpassade färger
37 |   
38 |
39 | #### Färgval, med möjlighet att definiera och nyttja egendefinierade färger; både ikonens text och bakgrundsfärg kan ändras
40 | 
41 |
42 | ## Installation
43 | Ladda ner zip, extrahera och kör WeekNumber.exe.
44 |
45 | En notis visas då WeekNumber är startad
46 |
47 | 
48 |
49 | Aktuellt veckonummer visas nu bland systemfältets ikoner, ser du inte veckonummer tryck på taktecknet (^) i systemfältet och klicka-håll och dra ned ikonen så den blir synlig.
50 |
51 |
52 | ## Hjälpavsnitt
53 | Alla funktioner är tillgängliga genom att höger-klicka på applikationens ikon i Windows systemfält.
54 | Om du inte ser applikationens ikon så tryck på taktecknet (^) vid systemfältet, klicka och håll inne musknappen medans du drar ikonen ned i systemfältet; då kommer ikonen fästas där och vara synlig.
55 |
56 | ### Högerklicks-meny:
57 | - **Om WeekNumber** - _Visar versionsinformation_
58 | - **Inställningar**
59 | - **Starta med Windows** - _Om ikryssad så startar applikationen automatiskt med Windows_
60 | - **Språk** - _Ändrar vilket språk som applikationen använder_
61 | - **English** - _Engelska_
62 | - **German** - _Tyska_
63 | - **Svenska**
64 | - **Applikationslogg**
65 | - **Använd applikationlogg** - _Om ikryssad så skriver applikationen till en loggfil_
66 | - **Visa applikationslogg** - _Om ovan är ikryssad så visas applikationens loggfil i en texteditor (teknisk loggfil)_
67 | - **Notiser**
68 | - **Visa uppstartsnotis** - _Om ikryssad så visar applikationen en uppstartsnotis_
69 |
70 |
71 |
72 | - **Visa ny veckonotis** - _Om ikryssad så visas en notis då aktuell vecka ändras_
73 |
74 |
75 |
76 | - **Använd tysta notiser** - _Om ikryssad så spelas inte något ljud upp då denna applikation visar notiser_
77 | - **Använd små / stora aktivitetsfältsikoner** - _Skiftar mellan stora och små aktivitetsfältsikoner. Har du svårt att se veckonumret? Testa att använda stora aktivitetsfältsikoner_
78 | - **Exportera inställningar..." - _Möjlighet att exportera / spara kopia av aktuella applikationsinställningar_
79 | - **Importera inställningar..." - _Möjlighet att importera tidigare exporterad / sparad kopia av applikationsinställningar_
80 | - **Kalender** - _Kalenderregler som appliationen använder sig av; vanligtvis tas detta från de regionella inställningar som är inställda på systemet, men de går alltså att justera manuellt här_
81 | - **'Första-dag-i-vecka'-regel** - _Kalenderregel, välj dag som en vecka startar på_
82 | - **'Årets-första-vecka'-regel** - _Ytterligare kalender-regel som anger vilket regelverk som ska nyttjas för årets första vecka_
83 | - **Ikon** - _Inställningar för applikationsikon_
84 | - **Ikonfärger** - _Möjlighet att anpassa appliktionens färger_
85 | - **Ikonupplösning** - _Möjlighet att anpassa WeekNumber-ikonens upplösning, om ikonen ser suddig ut kan en annan upplösning ge bättre ikonutseende_
86 | - **Grafikinställningar** - _Möjlighet att anpassa grafikalternativ som nyttjas då ikonen ritas av applikationen_
87 | - **Utjämningsläge**
88 | - **Kompositkvalitet**
89 | - **Interpolationsläge**
90 | - **Textkontrast**
91 | - **Spara ikon...** - _Sparar aktuell WeekNumber-ikon till en .ico fil_
92 | - **Få veckonummer för datum...** - _Visa veckonummer för angivet datum_
93 |
94 |
95 | - **Avsluta WeekNumber** - _Avslutar applikationen. Starta igen från Windows Startmeny_
96 |
97 | ## Donationer
98 | *- WeekNumber är fullständigt gratis och öppen källkod. Donationer uppskattas!*
99 |
100 | [](https://www.paypal.com/donate?hosted_button_id=7PN65YXN64DBG) __⟵__ _**Tryck här för att donera!**_
101 |
102 | [](https://ko-fi.com/G2G74W5F8) __⟵__ _**Tryck här för att köpa mig en kaffe!**_
103 |
104 | ## Statistik
105 | [](https://github.com/voltura/WeekNumber/issues)
106 | []()
107 | []()
108 |
109 | []()
110 | []()
111 | []()
112 | []()
113 | []()
114 | []()
115 | []()
116 | 
117 |
118 | 
119 |
--------------------------------------------------------------------------------
/Resources/Resources.de-DE.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/Resources.de-DE.Designer.cs
--------------------------------------------------------------------------------
/Resources/Resources.de-DE.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | WeekNumber von Voltura AB
122 |
123 | Copyright © Voltura AB 2018-2024
124 |
125 |
126 | Über WeekNumber
127 |
128 |
129 | ApplicationLog
130 |
131 |
132 | Anwendungs Log
133 |
134 |
135 | Blue
136 |
137 |
138 | IconBackground
139 |
140 |
141 | IconBackgroundBlue
142 |
143 |
144 | IconBackgroundGreen
145 |
146 |
147 | Hintergrund
148 |
149 |
150 | IconBackgroundRed
151 |
152 |
153 | Kalender Wochen Regeln
154 |
155 |
156 | Überprüfen Sie, ob Sie über einen Webbrowser zu dieser Adresse navigieren können:
157 |
158 |
159 | Hole Kalender Woche für Datum...
160 |
161 |
162 | Schließen
163 |
164 |
165 | Symbol Farben
166 |
167 |
168 | Tag
169 |
170 |
171 | DisplayStartupNotification
172 |
173 |
174 | Zeige Start Benachrichtigung
175 |
176 |
177 | Beende WeekNumber
178 |
179 |
180 | Aktualisierung der Symbolauflösung fehlgeschlagen
181 |
182 |
183 | Konnte Windows nicht über die Änderung der Taskleistensymbolgröße informieren.
184 |
185 | Bitte melden Sie dies an feedback@voltura.se!
186 |
187 |
188 | Konnte Symbol nicht festlegen.
189 |
190 | Bitte melden Sie dies an feedback@voltura.se!
191 |
192 |
193 | Konnte Kalenderwochenregel-Einstellung nicht festlegen.
194 |
195 | Bitte melden Sie dies an feedback@voltura.se!
196 |
197 |
198 | Farbe konnte nicht aktualisiert werden.
199 |
200 |
201 | Konnte Einstellung für den ersten Wochentag nicht aktualisieren.
202 |
203 | Bitte melden Sie dies an feedback@voltura.se!
204 |
205 |
206 | Konnte Registrierung nicht aktualisieren.
207 |
208 | Bitte melden Sie dies an feedback@voltura.se!
209 |
210 |
211 | Erster Tag
212 |
213 |
214 | Erster Tag der Woche
215 |
216 |
217 | Erste 4-Tage Woche
218 |
219 |
220 | Erste volle Woche
221 |
222 |
223 | IconForeground
224 |
225 |
226 | IconForegroundBlue
227 |
228 |
229 | IconForegroundGreen
230 |
231 |
232 | Foreground
233 |
234 |
235 | IconForegroundRed
236 |
237 |
238 | Freitag
239 |
240 |
241 | Green
242 |
243 |
244 | Icon
245 |
246 |
247 | 128x128
248 |
249 |
250 | 16x16
251 |
252 |
253 | 20x20
254 |
255 |
256 | 24x24
257 |
258 |
259 | 256x256
260 |
261 |
262 | 32x32
263 |
264 |
265 | 40x40
266 |
267 |
268 | 48x48
269 |
270 |
271 | 512x512
272 |
273 |
274 | 64x64
275 |
276 |
277 | IconResolution
278 |
279 |
280 | Symbol Auflösung
281 |
282 |
283 | Deine Version:
284 |
285 |
286 | Sie haben die neueste Version!
287 |
288 |
289 | MaxLogFileSizeInMB
290 |
291 |
292 | Montag
293 |
294 |
295 | Monat
296 |
297 |
298 | Es ist eine neue Version verfügbar
299 |
300 |
301 | Entschuldigung, diese Funktion ist noch nicht implementiert.
302 |
303 |
304 | OK
305 |
306 |
307 | Anwendungswebseite öffnen
308 |
309 |
310 | Red
311 |
312 |
313 | Colors reset
314 |
315 |
316 | Farben zurücksetzen
317 |
318 |
319 | Samstag
320 |
321 |
322 | Symbol speichern...
323 |
324 |
325 | Bitte wählen Sie die Hintergrundfarbe aus
326 |
327 |
328 | Bitte wählen Sie ein Datum, um die Wochennummer anzuzeigen
329 |
330 |
331 | Bitte wählen Sie die Vordergrundfarbe aus
332 |
333 |
334 | -
335 |
336 |
337 | Einstellungen
338 |
339 |
340 | ShowLog
341 |
342 |
343 | Zeige das Anwendungsprotokoll
344 |
345 |
346 | UseSilentNotifications
347 |
348 |
349 | Benutze versteckte Benachrichtigungen
350 |
351 |
352 | Benachrichtigungen
353 |
354 |
355 | Rechtsklick auf das Symbol im System-Tray für Funktionen und Einstellungen
356 |
357 |
358 | StartWithWindows
359 |
360 |
361 | Starte mit Windows
362 |
363 |
364 | Sonntag
365 |
366 |
367 | Benutze große Taskbar
368 |
369 |
370 | Benutze kleine Taskbar
371 |
372 |
373 | Donnerstag
374 |
375 |
376 | Dienstag
377 |
378 |
379 | Irgendetwas ist schiefgelaufen. Bitte an feedback@voltura.se melden!
380 |
381 |
382 | UseApplicationLog
383 |
384 |
385 | Benutze Anwendungsprotokoll
386 |
387 |
388 | version
389 |
390 |
391 | Mittwoch
392 |
393 |
394 | Woche
395 |
396 |
397 | Jahr
398 |
399 |
400 | Kalender
401 |
402 |
403 | Symbol
404 |
405 |
406 | DisplayWeekChangedNotification
407 |
408 |
409 | Zeige neue Woche Benachrichtigung
410 |
411 |
412 | Schließen Sie diese Anwendung und führen Sie sie manuell aus
413 |
414 |
415 | information
416 |
417 |
418 | Installationsprogramm-Prüfsumme inkorrekt, automatische Installation fehlgeschlagen.
419 |
420 |
421 | um die Anwendung zu aktualisieren.
422 |
423 |
424 | Versuchen Sie, es manuell über einen Webbrowser von dieser Adresse herunterzuladen:
425 |
426 |
427 | Umwandlung fehlgeschlagen
428 |
429 |
430 | en-US
431 |
432 |
433 | English
434 |
435 |
436 | Language
437 |
438 |
439 | Sprache
440 |
441 |
442 | WeekNumber von Voltura AB
443 |
444 |
445 | sv-SE
446 |
447 |
448 | Svenska
449 |
450 |
451 | de-DE
452 |
453 |
454 | Deutsch
455 |
456 |
457 | CompositingQuality
458 |
459 |
460 | Assume Linear
461 |
462 |
463 | Standard
464 |
465 |
466 | Gamma korrigiert
467 |
468 |
469 | Hohe Qualität
470 |
471 |
472 | Hohe Geschwindigkeit
473 |
474 |
475 | Kompositionsqualität
476 |
477 |
478 | Grafik Einstellungen
479 |
480 |
481 | InterpolationMode
482 |
483 |
484 | Bicubic
485 |
486 |
487 | Bilinear
488 |
489 |
490 | Standard
491 |
492 |
493 | Hoch
494 |
495 |
496 | Hohe Qualität Bicubic
497 |
498 |
499 | Hohe Qualität Bilinear
500 |
501 |
502 | Niedrig
503 |
504 |
505 | Interpolations Modus
506 |
507 |
508 | Nächster Nachbar
509 |
510 |
511 | Anti Alias
512 |
513 |
514 | SmoothingMode
515 |
516 |
517 | Standard
518 |
519 |
520 | Hohe Qualität
521 |
522 |
523 | Hohe Geschwindigkeit
524 |
525 |
526 | Glättungsmodus
527 |
528 |
529 | Keine
530 |
531 |
532 | TextContrast
533 |
534 |
535 | 1
536 |
537 |
538 | 2
539 |
540 |
541 | 3
542 |
543 |
544 | 4
545 |
546 |
547 | 5
548 |
549 |
550 | Text Kontrast
551 |
552 |
553 | Exportiere Einstellungen...
554 |
555 |
556 | Export der Einstellungen fehlgeschlagen!
557 |
558 |
559 | Import der Einstellungen fehlgeschlagen!
560 |
561 |
562 | Importiere Einstellungen...
563 |
564 |
565 | Einstellungen erfolgreich exportiert!
566 |
567 |
568 | Einstellungen erfolgreich importiert!
569 |
570 |
571 | IconBackgroundAlpha
572 |
573 |
574 | Benutze Transparenten Hintergrund
575 |
576 |
--------------------------------------------------------------------------------
/Resources/Resources.en-US.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/Resources.en-US.Designer.cs
--------------------------------------------------------------------------------
/Resources/Resources.sv-SE.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/Resources.sv-SE.Designer.cs
--------------------------------------------------------------------------------
/Resources/WeekNumber.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/WeekNumber.bmp
--------------------------------------------------------------------------------
/Resources/infoIconWhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/infoIconWhite.png
--------------------------------------------------------------------------------
/Resources/weekicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Resources/weekicon.ico
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Only latest version will receive updates. Make sure you are on latest version before reporting an issue.
6 |
7 | ## Reporting a Vulnerability
8 |
9 | Register an issue here in the WeekNumber repo on GitHub, as detailed as possible.
10 |
--------------------------------------------------------------------------------
/Settings.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using Microsoft.Win32;
4 | using System;
5 | using System.Configuration;
6 | using System.Globalization;
7 | using System.IO;
8 | using System.Windows.Forms;
9 | using System.Xml;
10 |
11 | #endregion Using statements
12 |
13 | namespace WeekNumber
14 | {
15 | internal static class Settings
16 | {
17 | #region Internal static property that updates registry for application to start when Windows start
18 |
19 | internal static bool StartWithWindows
20 | {
21 | get
22 | {
23 | bool startWithWindows = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\", Application.ProductName, null) != null;
24 | return startWithWindows;
25 | }
26 | set
27 | {
28 | using (RegistryKey registryKey = Registry.CurrentUser)
29 | using (RegistryKey regRun = registryKey?.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run\", true))
30 | {
31 | if (value)
32 | {
33 | regRun?.SetValue(Application.ProductName, Application.ExecutablePath);
34 | UpdateSetting(Resources.StartWithWindows, true.ToString());
35 | }
36 | else
37 | {
38 | if (regRun?.GetValue(Application.ProductName) != null)
39 | regRun?.DeleteValue(Application.ProductName);
40 | UpdateSetting(Resources.StartWithWindows, false.ToString());
41 | }
42 | registryKey?.Flush();
43 | }
44 | }
45 | }
46 |
47 | #endregion Internal static property that updates registry for application to start when Windows start
48 |
49 | #region Internal static methods
50 |
51 | internal static bool SettingIsValue(string setting, string value)
52 | {
53 | CreateSettings();
54 | return ConfigurationManager.AppSettings.Get(setting) == value;
55 | }
56 |
57 | internal static string GetSetting(string setting)
58 | {
59 | CreateSettings();
60 | return ConfigurationManager.AppSettings.Get(setting);
61 | }
62 |
63 | internal static int GetIntSetting(string setting, int defaultValue = 0)
64 | {
65 | if (int.TryParse(GetSetting(setting), out int settingInt))
66 | {
67 | return settingInt;
68 | }
69 | return defaultValue;
70 | }
71 |
72 | internal static void UpdateSetting(string setting, string value)
73 | {
74 | CreateSettings();
75 | Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
76 | KeyValueConfigurationCollection settings = configFile.AppSettings.Settings;
77 | settings[setting].Value = value;
78 | configFile.Save(ConfigurationSaveMode.Modified);
79 | ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
80 | Log.Info = $"'{setting}' set to '{value}'";
81 | }
82 |
83 | ///
84 | /// Creates a backup of the applications current settings file
85 | ///
86 | internal static bool BackupSettings(string fileName = "")
87 | {
88 | Log.LogCaller();
89 | string settingsFile = Application.ExecutablePath + ".config";
90 | string settingsBackupDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp");
91 | string settingsFileBackup = Path.Combine(settingsBackupDir, Application.ExecutablePath + ".config.bak");
92 | if (fileName != string.Empty)
93 | {
94 | settingsBackupDir = Path.GetDirectoryName(fileName);
95 | settingsFileBackup = fileName;
96 | }
97 | try
98 | {
99 | if (settingsFile.Equals(settingsFileBackup, StringComparison.InvariantCultureIgnoreCase))
100 | {
101 | Log.ErrorString = $"Cannot create copy of settings file since it has same fullpath as original: '{settingsFileBackup}'";
102 | return false;
103 | }
104 | if (File.Exists(settingsFile))
105 | {
106 | if (!Directory.Exists(settingsBackupDir)) Directory.CreateDirectory(settingsBackupDir);
107 | File.Copy(settingsFile, settingsFileBackup, true);
108 | Log.Info = $"Copy of settings file created: '{settingsFileBackup}'.";
109 | return true;
110 | }
111 | }
112 | catch (Exception ex)
113 | {
114 | Log.Error = ex;
115 | }
116 | Log.ErrorString = $"Failed to create copy of settings file: '{settingsFileBackup}'";
117 | return false;
118 | }
119 |
120 | internal static void RestoreBackupSettings()
121 | {
122 | Log.LogCaller();
123 | string settingsFile = Application.ExecutablePath + ".config";
124 | string settingsBackupDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp");
125 | string settingsFileBackup = Path.Combine(settingsBackupDir, Application.ExecutablePath + ".config.bak");
126 | try
127 | {
128 | if (!File.Exists(settingsFileBackup)) return;
129 | if (!File.Exists(settingsFile)) CreateSettings();
130 | XmlDocument doc = new XmlDocument();
131 | doc.Load(settingsFileBackup);
132 | XmlNodeList nodeList = doc.SelectNodes("/configuration/appSettings");
133 | foreach (XmlNode node in nodeList)
134 | foreach (XmlNode child in node.ChildNodes)
135 | if (child.Name == "add")
136 | {
137 | XmlAttributeCollection attribs = child.Attributes;
138 | if (attribs.Count == 2)
139 | {
140 | string settingsName = attribs[0].Value;
141 | string settingsValue = attribs[1].Value;
142 | try
143 | {
144 | UpdateSetting(settingsName, settingsValue);
145 | }
146 | catch (Exception ex)
147 | {
148 | Log.Error = ex;
149 | }
150 | }
151 | }
152 | File.Delete(settingsFileBackup);
153 | Log.Info = "Removed backup settings file after restore.";
154 | }
155 | catch (Exception ex)
156 | {
157 | Log.Error = ex;
158 | }
159 | }
160 |
161 | ///
162 | /// Import settings from file
163 | ///
164 | ///
165 | ///
166 | internal static bool ImportSettings(string fileToImport)
167 | {
168 | Log.LogCaller();
169 | string settingsFile = Application.ExecutablePath + ".config";
170 | try
171 | {
172 | if (!File.Exists(fileToImport))
173 | {
174 | Log.ErrorString = $"Settings file '{fileToImport}' not found, no import made.";
175 | return false;
176 | }
177 | if (!File.Exists(settingsFile)) CreateSettings();
178 | XmlDocument doc = new XmlDocument();
179 | doc.Load(fileToImport);
180 | XmlNodeList nodeList = doc.SelectNodes("/configuration/appSettings");
181 | foreach (XmlNode node in nodeList)
182 | foreach (XmlNode child in node.ChildNodes)
183 | if (child.Name == "add")
184 | {
185 | XmlAttributeCollection attribs = child.Attributes;
186 | if (attribs.Count == 2)
187 | {
188 | string settingsName = attribs[0].Value;
189 | string settingsValue = attribs[1].Value;
190 | try
191 | {
192 | UpdateSetting(settingsName, settingsValue);
193 | }
194 | catch (Exception ex)
195 | {
196 | Log.Error = ex;
197 | }
198 | }
199 | }
200 | }
201 | catch (Exception ex)
202 | {
203 | Log.ErrorString = $"Failed to import settings file '{fileToImport}'.";
204 | Log.Error = ex;
205 | return false;
206 | }
207 | Log.Info = $"Imported settings from '{fileToImport}'.";
208 | return true;
209 | }
210 |
211 | ///
212 | /// Set application culture info
213 | ///
214 | internal static void SetCultureInfoFromSystemOrSettings()
215 | {
216 | Log.LogCaller();
217 | try
218 | {
219 | string language = GetSetting(Resources.Language);
220 | if (string.IsNullOrEmpty(language)) // First run there is no setting for language
221 | {
222 | if (CultureInfo.CurrentCulture.Name == Resources.Swedish)
223 | {
224 | language = Resources.Swedish;
225 | }
226 | else if (CultureInfo.CurrentCulture.Name == Resources.German)
227 | {
228 | language = Resources.German;
229 | }
230 | else
231 | {
232 | language = Resources.English;
233 | }
234 | UpdateSetting(Resources.Language, language);
235 | }
236 | System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(language, false);
237 | System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(language, false);
238 | Log.Info = $"Set application Culture to '{language}'";
239 | }
240 | catch (Exception ex)
241 | {
242 | Log.Error = ex;
243 | System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(Resources.English, false);
244 | System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(Resources.English, false);
245 | Log.Info = $"Set application Culture to '{Resources.English}'";
246 | }
247 | }
248 |
249 |
250 | #endregion Internal static methods
251 |
252 | #region Private method that creates the application settings file if needed
253 |
254 | private static void CreateSettings()
255 | {
256 | string settingsFile = Application.ExecutablePath + ".config";
257 | if (!File.Exists(settingsFile) || !File.ReadAllText(settingsFile).Contains("Language"))
258 | {
259 | Log.LogCaller();
260 | CultureInfo currentCultureInfo = CultureInfo.CurrentCulture;
261 | DayOfWeek firstDay = currentCultureInfo.DateTimeFormat.FirstDayOfWeek;
262 | CalendarWeekRule calendarWeekRule = currentCultureInfo.DateTimeFormat.CalendarWeekRule;
263 | string xml = $@"
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 | ";
289 | File.Delete(settingsFile);
290 | File.WriteAllText(settingsFile, xml, System.Text.Encoding.UTF8);
291 | Log.Info = $"Created '{settingsFile}'";
292 | }
293 | }
294 |
295 | #endregion Private method that creates the application settings file if needed
296 | }
297 | }
--------------------------------------------------------------------------------
/TaskbarGui.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using Microsoft.Win32;
4 | using System;
5 | using System.Threading;
6 | using System.Windows.Forms;
7 |
8 | #region Test code
9 | /*
10 | using System.Reflection;
11 | using System.Runtime.InteropServices;
12 | using System.Drawing;
13 | */
14 | #endregion Test code
15 |
16 | #endregion Using statements
17 |
18 | namespace WeekNumber
19 | {
20 | internal class TaskbarGui : IDisposable, IGui
21 | {
22 | #region Public event handler (update icon request)
23 |
24 | public event EventHandler UpdateRequest;
25 |
26 | #endregion Public event handler (update icon request)
27 |
28 | #region Private variables
29 |
30 | private NotifyIcon _notifyIcon;
31 | private readonly WeekNumberContextMenu _contextMenu;
32 | private int _latestWeek;
33 |
34 | #endregion Private variables
35 |
36 | #region Constructor
37 |
38 | internal TaskbarGui(int week, int iconResolution = (int)IconSize.Icon256)
39 | {
40 | Log.LogCaller();
41 | _latestWeek = week;
42 | _contextMenu = new WeekNumberContextMenu();
43 | _notifyIcon = GetNotifyIcon(_contextMenu.ContextMenu);
44 | UpdateIcon(week, ref _notifyIcon, iconResolution);
45 | _notifyIcon.DoubleClick += NotifyIcon_DoubleClick;
46 |
47 | #region Test code
48 | /* test code
49 | Rectangle rect =NotifyIconHelper.GetIconRect(_notifyIcon);*/
50 | #endregion Test code
51 |
52 | if (Settings.SettingIsValue(Resources.DisplayStartupNotification, "True"))
53 | {
54 | DisplayUserInfoBalloonTip($"{_notifyIcon.Text}\r\n{Resources.StartupMessageText}");
55 | }
56 | _contextMenu.SettingsChangedHandler += OnSettingsChange;
57 | }
58 |
59 | #endregion Constructor
60 |
61 | #region Display NotifyIcon BalloonTip
62 |
63 | private void DisplayUserInfoBalloonTip(string message)
64 | {
65 | Log.LogCaller();
66 | bool siletMsg = Settings.SettingIsValue(Resources.UseSilentNotifications, "True");
67 | object currentSound = null;
68 | if (siletMsg)
69 | {
70 | using (RegistryKey regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings", true))
71 | {
72 | currentSound = regKey.GetValue("NOC_GLOBAL_SETTING_ALLOW_NOTIFICATION_SOUND");
73 | regKey.SetValue("NOC_GLOBAL_SETTING_ALLOW_NOTIFICATION_SOUND", 0);
74 | regKey.Flush();
75 | regKey.Close();
76 | }
77 | }
78 | _notifyIcon.ShowBalloonTip(10000, Message.CAPTION, message, ToolTipIcon.None);
79 | if (siletMsg)
80 | {
81 | using (RegistryKey regKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings", true))
82 | {
83 | System.Threading.Thread.Sleep(1000);
84 | if (currentSound is null)
85 | {
86 | regKey.DeleteValue("NOC_GLOBAL_SETTING_ALLOW_NOTIFICATION_SOUND");
87 | }
88 | else
89 | {
90 | regKey.SetValue("NOC_GLOBAL_SETTING_ALLOW_NOTIFICATION_SOUND", currentSound);
91 | }
92 | regKey.Flush();
93 | regKey.Close();
94 | }
95 | }
96 | }
97 |
98 | #endregion Display NotifyIcon BalloonTip
99 |
100 | #region Private event handlers
101 |
102 | private void OnSettingsChange(object sender, EventArgs e)
103 | {
104 | UpdateRequest?.Invoke(null, null);
105 | }
106 | private void NotifyIcon_DoubleClick(object sender, EventArgs e)
107 | {
108 | Forms.DateForm.Display();
109 | }
110 |
111 | #endregion Private event handlers
112 |
113 | #region Public UpdateIcon method
114 |
115 | ///
116 | /// Updates icon on GUI with given week number
117 | ///
118 | /// The week number to display on icon
119 | /// The width and height of the icon
120 | /// Redraw context menu
121 | public void UpdateIcon(int weekNumber, int iconResolution = (int)IconSize.Icon256, bool redrawContextMenu = false)
122 | {
123 | UpdateIcon(weekNumber, ref _notifyIcon, iconResolution);
124 | if (redrawContextMenu)
125 | {
126 | _contextMenu.CreateContextMenu();
127 | _notifyIcon.ContextMenu = _contextMenu.ContextMenu;
128 | }
129 | }
130 |
131 | #endregion Public UpdateIcon method
132 |
133 | #region Private UpdateIcon method
134 |
135 | private void UpdateIcon(int weekNumber, ref NotifyIcon notifyIcon, int iconResolution)
136 | {
137 | Log.LogCaller();
138 | try
139 | {
140 | string weekDayPrefix = string.Empty;
141 | string longDateString = DateTime.Now.ToLongDateString();
142 | const string SWEDISH_LONG_DATE_PREFIX_STRING = "den ";
143 | if (Thread.CurrentThread.CurrentUICulture.Name == Resources.Swedish || longDateString.StartsWith(SWEDISH_LONG_DATE_PREFIX_STRING))
144 | {
145 | weekDayPrefix = Message.SWEDISH_DAY_OF_WEEK_PREFIX[(int)DateTime.Now.DayOfWeek];
146 | }
147 | notifyIcon.Text = $"{Resources.Week} {weekNumber}\r\n{weekDayPrefix}{longDateString}";
148 | System.Drawing.Icon prevIcon = notifyIcon.Icon;
149 | notifyIcon.Icon = WeekIcon.GetIcon(weekNumber, iconResolution);
150 | WeekIcon.CleanupIcon(ref prevIcon);
151 | }
152 | finally
153 | {
154 | if (_latestWeek != weekNumber)
155 | {
156 | if (Settings.SettingIsValue(Resources.DisplayWeekChangedNotification, "True"))
157 | {
158 | DisplayUserInfoBalloonTip(notifyIcon.Text);
159 | }
160 | _latestWeek = weekNumber;
161 | }
162 | }
163 | }
164 |
165 | #endregion Private UpdateIcon method
166 |
167 | #region Private helper property to create NotifyIcon
168 |
169 | private static NotifyIcon GetNotifyIcon(ContextMenu contextMenu)
170 | {
171 | return new NotifyIcon { Visible = true, ContextMenu = contextMenu };
172 | }
173 |
174 | #endregion Private helper property to create NotifyIcon
175 |
176 | #region IDisposable methods
177 |
178 | ///
179 | /// Disposes the GUI resources
180 | ///
181 | public void Dispose()
182 | {
183 | Dispose(true);
184 | GC.SuppressFinalize(this);
185 | }
186 |
187 | protected virtual void Dispose(bool disposing)
188 | {
189 | if (!disposing)
190 | {
191 | return;
192 | }
193 | CleanupNotifyIcon();
194 | _contextMenu.Dispose();
195 | }
196 |
197 | private void CleanupNotifyIcon()
198 | {
199 | if (_notifyIcon != null)
200 | {
201 | _notifyIcon.Visible = false;
202 | if (_notifyIcon.Icon != null)
203 | {
204 | NativeMethods.DestroyIcon(_notifyIcon.Icon.Handle);
205 | _notifyIcon.Icon?.Dispose();
206 | }
207 | _notifyIcon.ContextMenu?.MenuItems.Clear();
208 | _notifyIcon.ContextMenu?.Dispose();
209 | _notifyIcon.Dispose();
210 | _notifyIcon = null;
211 | }
212 | }
213 |
214 | #endregion IDisposable methods
215 | }
216 |
217 | /* Use this to clear icon area instead, inspiration code only, need modification, but with area of icon then maybe move mouse over it programmatically instead of current more complex solution
218 |
219 |
220 |
221 |
222 | sealed class NotifyIconHelper
223 | {
224 |
225 | public static Rectangle GetIconRect(NotifyIcon icon)
226 | {
227 | RECT rect = new RECT();
228 | NOTIFYICONIDENTIFIER notifyIcon = new NOTIFYICONIDENTIFIER();
229 |
230 | notifyIcon.cbSize = Marshal.SizeOf(notifyIcon);
231 | //use hWnd and id of NotifyIcon instead of guid is needed
232 | notifyIcon.hWnd = GetHandle(icon);
233 | notifyIcon.uID = GetId(icon);
234 |
235 | int hresult = Shell_NotifyIconGetRect(ref notifyIcon, out rect);
236 | //rect now has the position and size of icon
237 |
238 | return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
239 | }
240 |
241 | private static int GetIconID(NotifyIcon icon)
242 | {
243 | RECT rect = new RECT();
244 | NOTIFYICONIDENTIFIER notifyIcon = new NOTIFYICONIDENTIFIER();
245 |
246 | notifyIcon.cbSize = Marshal.SizeOf(notifyIcon);
247 | //use hWnd and id of NotifyIcon instead of guid is needed
248 | notifyIcon.hWnd = GetHandle(icon);
249 | notifyIcon.uID = GetId(icon);
250 |
251 | int hresult = Shell_NotifyIconGetRect(ref notifyIcon, out rect);
252 | //rect now has the position and size of icon
253 |
254 | return notifyIcon.uID;
255 | }
256 |
257 | [StructLayout(LayoutKind.Sequential)]
258 | private struct RECT
259 | {
260 | public Int32 left;
261 | public Int32 top;
262 | public Int32 right;
263 | public Int32 bottom;
264 | }
265 |
266 | [StructLayout(LayoutKind.Sequential)]
267 | private struct NOTIFYICONIDENTIFIER
268 | {
269 | public Int32 cbSize;
270 | public IntPtr hWnd;
271 | public Int32 uID;
272 | public Guid guidItem;
273 | }
274 |
275 | [DllImport("shell32.dll", SetLastError = true)]
276 | private static extern int Shell_NotifyIconGetRect([In] ref NOTIFYICONIDENTIFIER identifier, [Out] out RECT iconLocation);
277 |
278 | private static FieldInfo windowField = typeof(NotifyIcon).GetField("window", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
279 | private static IntPtr GetHandle(NotifyIcon icon)
280 | {
281 | if (windowField == null) throw new InvalidOperationException("[Useful error message]");
282 | NativeWindow window = windowField.GetValue(icon) as NativeWindow;
283 |
284 | if (window == null) throw new InvalidOperationException("[Useful error message]"); // should not happen?
285 | return window.Handle;
286 | }
287 |
288 | private static FieldInfo idField = typeof(NotifyIcon).GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
289 |
290 | private static int GetId(NotifyIcon icon)
291 | {
292 | if (idField == null) throw new InvalidOperationException("[Useful error message]");
293 | return (int)idField.GetValue(icon);
294 | }
295 |
296 | }
297 |
298 | */
299 | }
--------------------------------------------------------------------------------
/TaskbarUtil.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using Microsoft.Win32;
4 | using System;
5 |
6 | #endregion Using statements
7 |
8 | namespace WeekNumber
9 | {
10 | internal static class TaskbarUtil
11 | {
12 | #region Private registry constants
13 |
14 | private const string EXPLORER_ADVANCED_REG_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
15 | private const string TASKBAR_SMALL_ICONS_REG_NAME = "TaskbarSmallIcons";
16 |
17 | #endregion Private registry constants
18 |
19 | #region Internal taskbar method
20 |
21 | internal static void ToogleTaskbarIconSize()
22 | {
23 | try
24 | {
25 | using (RegistryKey key = Registry.CurrentUser.OpenSubKey(EXPLORER_ADVANCED_REG_KEY, true))
26 | {
27 | if (key is null)
28 | {
29 | Message.Show(Resources.FailedToUpdateRegistry);
30 | return;
31 | }
32 | int newValue = Math.Abs(((int)key?.GetValue(TASKBAR_SMALL_ICONS_REG_NAME, 0, RegistryValueOptions.None)) - 1);
33 | key?.SetValue(TASKBAR_SMALL_ICONS_REG_NAME, newValue, RegistryValueKind.DWord);
34 | Log.Info = $"{TASKBAR_SMALL_ICONS_REG_NAME}={(newValue == 0 ? "false" : "true")}";
35 | }
36 | }
37 | catch (Exception ex)
38 | {
39 | Message.Show(Resources.FailedToUpdateRegistry, ex);
40 | return;
41 | }
42 | try
43 | {
44 | if (!NativeMethods.SendNotifyMessage((IntPtr)NativeMethods.HWND_BROADCAST,
45 | NativeMethods.WM_SETTINGCHANGE, UIntPtr.Zero, "TraySettings")) //NOTE: Will only work for English Windows UI locale
46 | {
47 | Message.Show(Resources.FailedToNotifyWindowsOfTaskbarIconSizeChange);
48 | }
49 | }
50 | catch (Exception ex)
51 | {
52 | Message.Show(Resources.FailedToNotifyWindowsOfTaskbarIconSizeChange, ex);
53 | }
54 | }
55 |
56 | #endregion Internal taskbar method
57 |
58 | #region Internal taskbar function
59 |
60 | internal static bool UsingSmallTaskbarButtons()
61 | {
62 | try
63 | {
64 | using (RegistryKey key = Registry.CurrentUser.OpenSubKey(EXPLORER_ADVANCED_REG_KEY, false))
65 | {
66 | return (int)key?.GetValue(TASKBAR_SMALL_ICONS_REG_NAME, 0, RegistryValueOptions.None) != 0;
67 | }
68 | }
69 | catch (Exception ex)
70 | {
71 | Log.LogCaller();
72 | Log.Error = ex;
73 | }
74 | return true;
75 | }
76 |
77 | #endregion Internal taskbar function
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Tools/fart199b_win32.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/Tools/fart199b_win32.zip
--------------------------------------------------------------------------------
/Week.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Globalization;
5 |
6 | #endregion Using statements
7 |
8 | namespace WeekNumber
9 | {
10 | internal class Week
11 | {
12 | #region Private variable that holds active week
13 |
14 | private int _week;
15 |
16 | #endregion Private variable that holds active week
17 |
18 | #region Constructor that initiates active week
19 |
20 | ///
21 | /// Initiates the week to current
22 | ///
23 | public Week()
24 | {
25 | _week = Current();
26 | }
27 |
28 | #endregion Constructor that initiates active week
29 |
30 | #region Internal static week strings
31 |
32 | internal const string CalendarWeekRuleString = nameof(CalendarWeekRule);
33 | internal const string FirstDay = nameof(CalendarWeekRule.FirstDay);
34 | internal const string FirstFourDayWeek = nameof(CalendarWeekRule.FirstFourDayWeek);
35 | internal const string FirstFullWeek = nameof(CalendarWeekRule.FirstFullWeek);
36 | internal const string DayOfWeekString = nameof(DayOfWeek);
37 | internal const string Monday = nameof(DayOfWeek.Monday);
38 | internal const string Tuesday = nameof(DayOfWeek.Tuesday);
39 | internal const string Wednesday = nameof(DayOfWeek.Wednesday);
40 | internal const string Thursday = nameof(DayOfWeek.Thursday);
41 | internal const string Friday = nameof(DayOfWeek.Friday);
42 | internal const string Saturday = nameof(DayOfWeek.Saturday);
43 | internal const string Sunday = nameof(DayOfWeek.Sunday);
44 |
45 | #endregion Internal static week strings
46 |
47 | #region Public function to check if week has changed
48 |
49 | ///
50 | /// Returns if week was changed since last check
51 | ///
52 | /// true|false
53 | public bool WasChanged()
54 | {
55 | bool changed = _week != Current();
56 | if (changed)
57 | {
58 | _week = Current();
59 | }
60 | Log.Info = $"Current week number is {_week} and this was {(changed ? "a change" : "same as last checked")}";
61 | return changed;
62 | }
63 |
64 | #endregion Public function to check if week has changed
65 |
66 | #region Public functions that returns week number based on calendar rules
67 |
68 | ///
69 | /// Get current week based on calendar rules in application settings
70 | ///
71 | /// Current week as int based on calendar rules in application settings
72 | public static int Current()
73 | {
74 | DayOfWeek dayOfWeek;
75 | CalendarWeekRule calendarWeekRule;
76 | dayOfWeek = Enum.TryParse(Settings.GetSetting(DayOfWeekString), true, out dayOfWeek) ?
77 | dayOfWeek : DayOfWeek.Monday;
78 | calendarWeekRule = Enum.TryParse(Settings.GetSetting(CalendarWeekRuleString), true,
79 | out calendarWeekRule) ? calendarWeekRule : CalendarWeekRule.FirstFourDayWeek;
80 | int week = CultureInfo.CurrentCulture.Calendar.
81 | GetWeekOfYear(DateTime.Now, calendarWeekRule, dayOfWeek);
82 | if (week == 53 && (!YearHas53Weeks(DateTime.Now.Year)))
83 | {
84 | week = 1;
85 | }
86 | Log.Info = $"Current week is #{week}";
87 | return week;
88 | }
89 |
90 | ///
91 | /// Get week number based on calendar rules in application settings
92 | ///
93 | /// Date for which to get week number for
94 | /// Week number as for supplied date
95 | public static int GetWeekNumber(DateTime date)
96 | {
97 | DayOfWeek dayOfWeek;
98 | CalendarWeekRule calendarWeekRule;
99 | dayOfWeek = Enum.TryParse(Settings.GetSetting(DayOfWeekString), true, out dayOfWeek) ?
100 | dayOfWeek : DayOfWeek.Monday;
101 | calendarWeekRule = Enum.TryParse(Settings.GetSetting(CalendarWeekRuleString), true,
102 | out calendarWeekRule) ? calendarWeekRule : CalendarWeekRule.FirstFourDayWeek;
103 | int week = CultureInfo.CurrentCulture.Calendar.
104 | GetWeekOfYear(date, calendarWeekRule, dayOfWeek);
105 | if (week == 53 && (!YearHas53Weeks(DateTime.Now.Year)))
106 | {
107 | week = 1;
108 | }
109 | Log.Info = $"Week number is {week} for date {date.Year}-{date.Month}-{date.Day}";
110 | return week;
111 | }
112 |
113 | #endregion Public functions that returns week number based on calendar rules
114 |
115 | #region Private helper functions to determine if it is week 1 or 53
116 |
117 | private static bool YearHas53Weeks(int year)
118 | {
119 | return Weeks(year) == 53;
120 | }
121 |
122 | private static int Weeks(int year)
123 | {
124 | int w = 52;
125 | if (P(year) == 4 || P(year - 1) == 3)
126 | {
127 | w++;
128 | }
129 | return w; // returns the number of weeks in that year
130 | }
131 |
132 | private static int P(int year)
133 | {
134 | return (int)(year + Math.Floor(year / 4f) - Math.Floor(year / 100f) + Math.Floor(year / 400f)) % 7;
135 | }
136 |
137 | #endregion Private helper functions to determine if it is week 1 or 53
138 | }
139 | }
--------------------------------------------------------------------------------
/WeekApplicationContext.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using Microsoft.Win32;
4 | using System;
5 | using System.Windows.Forms;
6 |
7 | #endregion Using statements
8 |
9 | namespace WeekNumber
10 | {
11 | internal class WeekApplicationContext : ApplicationContext
12 | {
13 | #region Internal Taskbar GUI
14 |
15 | internal IGui Gui;
16 |
17 | #endregion Internal Taskbar GUI
18 |
19 | #region Private variables
20 |
21 | private readonly Timer _timer;
22 | private int _currentWeek;
23 | private int _lastIconRes;
24 |
25 | #endregion Private variables
26 |
27 | #region Constructor
28 |
29 | internal WeekApplicationContext()
30 | {
31 | try
32 | {
33 | Log.LogCaller();
34 | Settings.StartWithWindows = Settings.SettingIsValue(Resources.StartWithWindows, true.ToString());
35 | Application.ApplicationExit += OnApplicationExit;
36 | SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged;
37 | _currentWeek = Week.Current();
38 | _lastIconRes = WeekIcon.GetIconResolution();
39 | Gui = new TaskbarGui(_currentWeek, _lastIconRes);
40 | Gui.UpdateRequest += GuiUpdateRequestHandler;
41 | _timer = GetTimer;
42 | }
43 | catch (Exception ex)
44 | {
45 | _timer?.Stop();
46 | Log.LogCaller();
47 | Message.Show(Resources.UnhandledException, ex);
48 | Application.Exit();
49 | }
50 | }
51 |
52 | #endregion Constructor
53 |
54 | #region Private Timer property
55 |
56 | private Timer GetTimer
57 | {
58 | get
59 | {
60 | if (_timer != null)
61 | {
62 | return _timer;
63 | }
64 | //int calculatedInterval = 86400000 - ((DateTime.Now.Hour * 3600000) + (DateTime.Now.Minute * 60000) + (DateTime.Now.Second * 1000));
65 | int calculatedInterval = 10000; // workaround for blurry icon due to Windows icon rendering bug, update icon every 10 seconds instead of when week change occurs only
66 | Timer timer = new Timer
67 | {
68 | Interval = calculatedInterval,
69 | Enabled = true
70 | };
71 | Log.Info = $"Timer interval={calculatedInterval / 1000}s";
72 | timer.Tick += OnTimerTick;
73 | return timer;
74 | }
75 | }
76 |
77 | #endregion Private Timer property
78 |
79 | #region Private event handlers
80 |
81 | private void GuiUpdateRequestHandler(object sender, EventArgs e)
82 | {
83 | Log.LogCaller();
84 | UpdateIcon(true, true);
85 | }
86 |
87 | private void OnApplicationExit(object sender, EventArgs e)
88 | {
89 | Log.LogCaller();
90 | Cleanup(false);
91 | }
92 |
93 | private void OnUserPreferenceChanged(object sender, EventArgs e)
94 | {
95 | Log.LogCaller();
96 | int iconRes = WeekIcon.GetIconResolution(true);
97 | if (iconRes != _lastIconRes)
98 | {
99 | UpdateIcon(true, true);
100 | _lastIconRes = iconRes;
101 | }
102 | }
103 |
104 | private void OnTimerTick(object sender, EventArgs e)
105 | {
106 | UpdateIcon();
107 | }
108 |
109 | private void UpdateIcon(bool force = false, bool redrawContextMenu = false)
110 | {
111 | if (_currentWeek == Week.Current() && force == false)
112 | {
113 | return;
114 | }
115 | _timer?.Stop();
116 | Application.DoEvents();
117 | try
118 | {
119 | Log.LogCaller();
120 | _currentWeek = Week.Current();
121 | int iconResolution = Settings.GetIntSetting(Resources.IconResolution, (int)IconSize.Icon256);
122 | Log.Info = $"Update icon with week number {_currentWeek} using resolution {iconResolution}x{iconResolution}, redraw context menu={redrawContextMenu}, forced update={force}";
123 | Gui?.UpdateIcon(_currentWeek, iconResolution, redrawContextMenu);
124 | }
125 | catch (Exception ex)
126 | {
127 | Message.Show(Resources.FailedToSetIcon, ex);
128 | Cleanup();
129 | throw;
130 | }
131 | if (_timer != null)
132 | {
133 | int calculatedInterval = 86400000 - ((DateTime.Now.Hour * 3600000) + (DateTime.Now.Minute * 60000) + (DateTime.Now.Second * 1000));
134 | _timer.Interval = calculatedInterval;
135 | Log.Info = $"Timer interval={calculatedInterval / 1000}s";
136 | _timer.Start();
137 | }
138 | }
139 |
140 | #endregion Private event handlers
141 |
142 | #region Private methods
143 |
144 | private void Cleanup(bool forceExit = true)
145 | {
146 | Log.LogCaller();
147 | _timer?.Stop();
148 | _timer?.Dispose();
149 | Gui?.Dispose();
150 | Gui = null;
151 | if (forceExit)
152 | {
153 | Application.Exit();
154 | }
155 | }
156 |
157 | #endregion Private methods
158 | }
159 | }
--------------------------------------------------------------------------------
/WeekIcon.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using System.Globalization;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Windows.Forms;
10 |
11 | #endregion Using statements
12 |
13 | namespace WeekNumber
14 | {
15 | internal static class WeekIcon
16 | {
17 | #region Icon Size
18 |
19 | private const int _defaultSize = (int)IconSize.Icon256;
20 | private const int _saveSize = (int)IconSize.Icon256;
21 |
22 | #endregion Icon Size
23 |
24 | #region Internal static functions
25 |
26 | internal static int GetIconResolution(bool forceUpdate = false)
27 | {
28 | int iconResolution = Settings.GetIntSetting(Resources.IconResolution, -1);
29 | double myDbl = 1.0d;
30 | if (forceUpdate || iconResolution == -1)
31 | {
32 | // guess what icon resolution to use based on system
33 | double winZoomLvl = GetWindowsZoom();
34 | bool usingSmallTaskbarIcons = TaskbarUtil.UsingSmallTaskbarButtons();
35 | myDbl = (double)System.Windows.SystemParameters.SmallIconHeight * winZoomLvl;
36 | if (!usingSmallTaskbarIcons) myDbl *= 1.5d;
37 | if (System.Windows.SystemParameters.PrimaryScreenWidth > 1600) myDbl *= 2.0d;
38 | Log.Info = $"SmallIconHeight={System.Windows.SystemParameters.SmallIconHeight}";
39 | Log.Info = $"WindowsZoomLevel={winZoomLvl * 100}";
40 | Log.Info = $"UsingSmallTaskbarButtons={usingSmallTaskbarIcons}";
41 | Log.Info = $"Guessed icon resolution={myDbl}x{myDbl}";
42 |
43 | // find closes match to existing configs (do not allow 16, 20, 24, 32, 40, 48, 64, 128)
44 | List list = new List { 256, 512 };
45 | int closest = list.Aggregate((x, y) => Math.Abs(x - myDbl) < Math.Abs(y - myDbl) ? x : y);
46 |
47 | Log.Info = $"Closest icon resolution={closest}x{closest}";
48 |
49 | Settings.UpdateSetting(Resources.IconResolution, closest.ToString());
50 | iconResolution = closest;
51 | }
52 |
53 | return iconResolution;
54 | }
55 |
56 | internal static Bitmap GetImage(int weekNumber)
57 | {
58 | Log.LogCaller();
59 | int size = 256;
60 | using (Bitmap bitmap = new Bitmap(size, size))
61 | using (Graphics graphics = Graphics.FromImage(bitmap))
62 | {
63 | try
64 | {
65 | graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
66 | graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
67 | graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
68 | graphics.TextContrast = 1;
69 | DrawBackgroundOnGraphics(graphics, size);
70 | DrawWeekNumberOnGraphics(weekNumber, graphics, size);
71 | return bitmap.Clone(new RectangleF(0, 0, size, size), System.Drawing.Imaging.PixelFormat.DontCare);
72 | }
73 | finally
74 | {
75 | graphics.Dispose();
76 | bitmap?.Dispose();
77 | }
78 | }
79 | }
80 |
81 | internal static Icon GetIcon(int weekNumber, int size = 0)
82 | {
83 | Log.LogCaller();
84 | if (size == 0)
85 | {
86 | Log.Info = $"Using default icon size {_defaultSize}x{_defaultSize}";
87 | size = _defaultSize;
88 | }
89 | Icon icon = null;
90 | using (Bitmap bitmap = new Bitmap(size, size))
91 | using (Graphics graphics = Graphics.FromImage(bitmap))
92 | {
93 | graphics.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)Settings.GetIntSetting(Resources.SmoothingMode, (int)System.Drawing.Drawing2D.SmoothingMode.HighQuality);
94 | graphics.CompositingQuality = (System.Drawing.Drawing2D.CompositingQuality)Settings.GetIntSetting(Resources.CompositingQuality, (int)System.Drawing.Drawing2D.CompositingQuality.HighQuality);
95 | graphics.InterpolationMode = (System.Drawing.Drawing2D.InterpolationMode)Settings.GetIntSetting(Resources.InterpolationMode, (int)System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic);
96 | graphics.TextContrast = Settings.GetIntSetting(Resources.TextContrast, 1);
97 | DrawBackgroundOnGraphics(graphics, size);
98 | DrawWeekNumberOnGraphics(weekNumber, graphics, size);
99 | IntPtr bHicon = bitmap.GetHicon();
100 | Icon newIcon = Icon.FromHandle(bHicon);
101 | icon = new Icon(newIcon, size, size);
102 | CleanupIcon(ref newIcon);
103 | }
104 | return icon;
105 | }
106 |
107 | internal static void CleanupIcon(ref Icon icon)
108 | {
109 | if (icon is null)
110 | {
111 | return;
112 | }
113 | NativeMethods.DestroyIcon(icon.Handle);
114 | icon.Dispose();
115 | }
116 |
117 | internal static bool SaveIcon(int weekNumber, string fullPath)
118 | {
119 | bool result = true;
120 | Icon icon = null;
121 |
122 | try
123 | {
124 | Log.LogCaller();
125 | icon = GetIcon(weekNumber, _saveSize);
126 | using (FileStream fs = new FileStream(fullPath, FileMode.Create,
127 | FileAccess.Write, FileShare.None))
128 | {
129 | icon.Save(fs);
130 | Log.Info = $"Save app icon as '{fullPath}'";
131 | }
132 | }
133 | catch (System.Exception ex)
134 | {
135 | Message.Show(Resources.UnhandledException, ex);
136 | result = false;
137 | }
138 | finally
139 | {
140 | CleanupIcon(ref icon);
141 | }
142 | return result;
143 | }
144 |
145 | #endregion Internal static functions
146 |
147 | #region Privare static helper methods
148 |
149 | private static void DrawBackgroundOnGraphics(Graphics graphics, int size = 0)
150 | {
151 | if (size == 0)
152 | {
153 | size = _defaultSize;
154 | }
155 | Color backgroundColor = Color.FromArgb(Settings.GetIntSetting(Resources.IconBackgroundAlpha),
156 | Settings.GetIntSetting(Resources.IconBackgroundRed),
157 | Settings.GetIntSetting(Resources.IconBackgroundGreen),
158 | Settings.GetIntSetting(Resources.IconBackgroundBlue));
159 | Color foregroundColor = Color.FromArgb(
160 | Settings.GetIntSetting(Resources.IconForegroundRed, 255),
161 | Settings.GetIntSetting(Resources.IconForegroundGreen, 255),
162 | Settings.GetIntSetting(Resources.IconForegroundBlue, 255));
163 | using (SolidBrush foregroundBrush = new SolidBrush(foregroundColor))
164 | using (SolidBrush backgroundBrush = new SolidBrush(backgroundColor))
165 | {
166 | float inset = (float)System.Math.Abs(size * .03125);
167 | graphics?.FillRectangle(backgroundBrush, inset, inset, size - inset, size - inset);
168 | using (Pen pen = new Pen(foregroundColor, inset * 2))
169 | {
170 | graphics?.DrawRectangle(pen, inset, inset, size - inset * 2, size - inset * 2);
171 | }
172 | float leftInset = (float)System.Math.Abs(size * .15625);
173 | graphics?.FillRectangle(foregroundBrush, leftInset, inset / 2, inset * 3, inset * 5);
174 | float rightInset = (float)System.Math.Abs(size * .75);
175 | graphics?.FillRectangle(foregroundBrush, rightInset, inset / 2, inset * 3, inset * 5);
176 | }
177 | }
178 |
179 | private static void DrawWeekNumberOnGraphics(int weekNumber, Graphics graphics, int size = 0)
180 | {
181 | if (size == 0) size = _defaultSize;
182 | float fontSize = (float)System.Math.Abs(size * .78125);
183 | // float insetX = (float)-(size > (int)IconSize.Icon16 ? System.Math.Abs(fontSize * .12) : System.Math.Abs(fontSize * .07));
184 | float insetY = (float)(size > (int)IconSize.Icon16 ? System.Math.Abs(fontSize * .2) : System.Math.Abs(fontSize * .08));
185 | Color foregroundColor = Color.FromArgb(
186 | Settings.GetIntSetting(Resources.IconForegroundRed),
187 | Settings.GetIntSetting(Resources.IconForegroundGreen),
188 | Settings.GetIntSetting(Resources.IconForegroundBlue));
189 |
190 | using (Font font = new Font("Aurulent Sans Mono", fontSize * 0.8f, FontStyle.Regular,
191 | GraphicsUnit.Pixel, 0, false))
192 | using (Brush brush = new SolidBrush(foregroundColor))
193 | graphics?.DrawString(weekNumber.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0'), font, brush, 0.0f, insetY);
194 | }
195 |
196 | private static double GetWindowsZoom()
197 | {
198 | return (double)(Screen.PrimaryScreen.WorkingArea.Width / System.Windows.SystemParameters.PrimaryScreenWidth);
199 | }
200 |
201 | #endregion Private static helper methods
202 | }
203 | }
--------------------------------------------------------------------------------
/WeekNumber.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {82D086D4-E145-4487-81FA-28BD3B1577D2}
6 | WinExe
7 | WeekNumber
8 | WeekNumber
9 | v4.8
10 | 512
11 | true
12 | false
13 | True
14 |
15 |
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 |
33 | x64
34 | true
35 | full
36 | false
37 | bin\x64\Debug\
38 | DEBUG;TRACE
39 | prompt
40 | 4
41 | true
42 | True
43 |
44 |
45 | x64
46 | pdbonly
47 | true
48 | bin\x64\Release\
49 | TRACE
50 | prompt
51 | 4
52 | false
53 | true
54 | bin\x64\Release\WeekNumber.xml
55 | false
56 | True
57 |
58 |
59 | true
60 | bin\x86\Debug\
61 | TRACE;DEBUG;CODE_ANALYSIS
62 | true
63 | full
64 | x86
65 | prompt
66 | true
67 | True
68 |
69 |
70 | bin\x86\Release\
71 | CODE_ANALYSIS;TRACE
72 | bin\x86\Release\WeekNumber.xml
73 | true
74 | true
75 | pdbonly
76 | x86
77 | prompt
78 | true
79 | True
80 |
81 |
82 | WeekNumber.Program
83 |
84 |
85 | Resources\weekicon.ico
86 |
87 |
88 | Properties\app.manifest
89 |
90 |
91 | true
92 |
93 |
94 | Properties\WeekNumber.snk
95 |
96 |
97 | false
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Component
114 |
115 |
116 | Form
117 |
118 |
119 | DateForm.cs
120 |
121 |
122 | Form
123 |
124 |
125 | MessageForm.cs
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | True
137 | True
138 | Resources.de-DE.resx
139 |
140 |
141 | Resources.resx
142 | True
143 | True
144 |
145 |
146 | True
147 | True
148 | Resources.en-US.resx
149 |
150 |
151 | True
152 | True
153 | Resources.sv-SE.resx
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | Designer
167 |
168 |
169 | Designer
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 | DateForm.cs
186 |
187 |
188 | MessageForm.cs
189 |
190 |
191 | ResXFileCodeGenerator
192 | Resources.de-DE.Designer.cs
193 | Designer
194 |
195 |
196 | ResXFileCodeGenerator
197 | Resources.Designer.cs
198 | WeekNumber
199 | Designer
200 |
201 |
202 | WeekNumber
203 | ResXFileCodeGenerator
204 | Resources.sv-SE.Designer.cs
205 | Designer
206 |
207 |
208 | ResXFileCodeGenerator
209 | Resources.en-US.Designer.cs
210 | WeekNumber
211 | Designer
212 |
213 |
214 |
215 |
216 |
217 | CMD /C TASKKILL /IM $(TargetFileName) /FI "STATUS eq RUNNING" /T /F
218 |
219 |
220 |
221 |
222 |
223 |
--------------------------------------------------------------------------------
/WeekNumber.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.11.35327.3
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeekNumber", "WeekNumber.csproj", "{82D086D4-E145-4487-81FA-28BD3B1577D2}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Debug|Any CPU.ActiveCfg = Debug|x86
19 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Debug|x64.ActiveCfg = Debug|x64
20 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Debug|x64.Build.0 = Debug|x64
21 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Debug|x86.ActiveCfg = Debug|x86
22 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Debug|x86.Build.0 = Debug|x86
23 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Release|Any CPU.ActiveCfg = Release|x86
24 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Release|x64.ActiveCfg = Release|x64
25 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Release|x64.Build.0 = Release|x64
26 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Release|x86.ActiveCfg = Release|x86
27 | {82D086D4-E145-4487-81FA-28BD3B1577D2}.Release|x86.Build.0 = Release|x86
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | GlobalSection(ExtensibilityGlobals) = postSolution
33 | SolutionGuid = {B395858B-07BD-439B-863C-1A9505DFFBEE}
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/WeekNumberMonitor/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("WeekNumberMonitor")]
6 | [assembly: AssemblyDescription("WeekNumberMonitor")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("Voltura AB")]
9 | [assembly: AssemblyProduct("WeekNumberMonitor")]
10 | [assembly: AssemblyCopyright("Copyright © Voltura AB 2024")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 | [assembly: ComVisible(false)]
14 | [assembly: Guid("65632C08-E70E-4C7F-94F2-BC68FBC42744")]
15 | [assembly: AssemblyVersion("1.0.0.*")]
16 | [assembly: AssemblyFileVersion("1.0.0.0")]
17 | [assembly: NeutralResourcesLanguage("en-US")]
--------------------------------------------------------------------------------
/WeekNumberMonitor/Program.cs:
--------------------------------------------------------------------------------
1 | #region Using statements
2 |
3 | using System;
4 | using System.Diagnostics;
5 | using System.Runtime;
6 | using System.Runtime.InteropServices;
7 |
8 | #endregion Using statements
9 |
10 | ///
11 | /// This program is used by WeekNumber to refresh taskbar notification area if WeekNumber.exe is process is terminated
12 | /// and its notification area icon is still displayed, even though the WeekNumber application is not running.
13 | /// This projects compiled executable file contents has been manually converted into a base64 encoded string which is utilized from
14 | /// WeekNumber::MonitorProcess class which writes the exe to %LOCALAPPDATA%\temp and starts the program when WeekNumber.exe
15 | /// is started.
16 | ///
17 | internal class Program
18 | {
19 | #region Application starting point
20 |
21 | [STAThread]
22 | private static void Main(string[] args)
23 | {
24 | try
25 | {
26 | int id = int.Parse(args[0]);
27 | GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
28 | GCSettings.LatencyMode = GCLatencyMode.Batch;
29 | using (Process p = Process.GetProcessById(id))
30 | {
31 | p.WaitForExit();
32 | }
33 | }
34 | catch (Exception)
35 | {
36 | }
37 | RefreshTrayArea();
38 | }
39 |
40 | #endregion Application starting point
41 |
42 | #region Logic for refreshing taskbar notification area
43 |
44 | [StructLayout(LayoutKind.Sequential)]
45 | private struct RECT
46 | {
47 | public int left;
48 | public int top;
49 | public int right;
50 | public int bottom;
51 | }
52 |
53 | [DllImport("user32.dll")]
54 | private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
55 |
56 | [DllImport("user32.dll")]
57 | private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
58 | string lpszWindow);
59 |
60 | [DllImport("user32.dll")]
61 | private static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
62 |
63 | [DllImport("user32.dll")]
64 | private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
65 |
66 | private static void RefreshTrayArea()
67 | {
68 | IntPtr systemTrayContainerHandle = FindWindow("Shell_TrayWnd", null);
69 | IntPtr systemTrayHandle = FindWindowEx(systemTrayContainerHandle, IntPtr.Zero, "TrayNotifyWnd", null);
70 | IntPtr sysPagerHandle = FindWindowEx(systemTrayHandle, IntPtr.Zero, "SysPager", null);
71 | IntPtr notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32", "Notification Area");
72 | if (notificationAreaHandle == IntPtr.Zero)
73 | {
74 | notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32",
75 | "User Promoted Notification Area");
76 | IntPtr notifyIconOverflowWindowHandle = FindWindow("NotifyIconOverflowWindow", null);
77 | IntPtr overflowNotificationAreaHandle = FindWindowEx(notifyIconOverflowWindowHandle, IntPtr.Zero,
78 | "ToolbarWindow32", "Overflow Notification Area");
79 | RefreshTrayArea(overflowNotificationAreaHandle);
80 | }
81 | RefreshTrayArea(notificationAreaHandle);
82 | }
83 |
84 | private static void RefreshTrayArea(IntPtr windowHandle)
85 | {
86 | const uint wmMousemove = 0x0200;
87 | GetClientRect(windowHandle, out RECT rect);
88 | for (var x = 0; x < rect.right; x += 5)
89 | for (var y = 0; y < rect.bottom; y += 5)
90 | SendMessage(windowHandle, wmMousemove, 0, (y << 16) + x);
91 | }
92 |
93 | #endregion Logic for refreshing taskbar notification area
94 | }
95 |
--------------------------------------------------------------------------------
/WeekNumberMonitor/WeekNumber.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voltura/WeekNumber/9017ce446081122109315f85f4fcc63e3fcdfbdd/WeekNumberMonitor/WeekNumber.snk
--------------------------------------------------------------------------------
/WeekNumberMonitor/WeekNumberMonitor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {89755684-7EB2-4687-B21F-5B6A7D55C7DB}
6 | WinExe
7 | WeekNumberMonitor
8 | WeekNumberMonitor
9 | v4.8
10 | 512
11 | true
12 | false
13 | True
14 |
15 |
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 |
33 | bin\x86\Release\
34 | TRACE
35 |
36 |
37 | true
38 | true
39 | none
40 | x86
41 | prompt
42 | true
43 | True
44 |
45 |
46 |
47 |
48 |
49 |
50 | true
51 |
52 |
53 | WeekNumber.snk
54 |
55 |
56 | false
57 |
58 |
59 | true
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | False
76 | Microsoft .NET Framework 4.6.1 %28x86 and x64%29
77 | true
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/WeekNumberMonitor/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | msbuild WeekNumber.sln /p:Platform=x86 /t:Clean,Build /property:Configuration=Release -maxcpucount
2 |
--------------------------------------------------------------------------------